Organize files, clean up formatting, add TODOs

This commit is contained in:
Matt Nadareski
2022-06-15 22:53:41 -07:00
parent 9e0abe7c5d
commit f1803b9f3a
23 changed files with 432 additions and 382 deletions

View File

@@ -18,7 +18,7 @@ using System;
using System.IO;
using LibGSF.Input;
namespace LibMSI
namespace LibMSI.Internal
{
internal class LibmsiIStream : Stream
{

View File

@@ -67,9 +67,10 @@
using System;
using System.Collections.Generic;
using static LibMSI.MsiPriv;
using LibMSI.Views;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Internal
{
#region Generated Enums

View File

@@ -24,13 +24,12 @@ using System.Linq;
using System.Text;
using LibGSF.Input;
using LibGSF.Output;
using static LibMSI.LibmsiQuery;
using static LibMSI.LibmsiRecord;
using static LibMSI.MsiPriv;
using LibMSI.Views;
using static LibMSI.LibmsiTypes;
using static LibMSI.StringTable;
using static LibMSI.Internal.MsiPriv;
using static LibMSI.Internal.StringTable;
namespace LibMSI
namespace LibMSI.Internal
{
internal class LibmsiColumnInfo
{
@@ -160,7 +159,7 @@ namespace LibMSI
#region Functions
public static int BytesPerColumn(LibmsiDatabase db, LibmsiColumnInfo col, int bytes_per_strref)
public static int BytesPerColumn(LibmsiColumnInfo col, int bytes_per_strref)
{
if (MSITYPE_IS_BINARY(col.Type))
return 2;
@@ -194,7 +193,7 @@ namespace LibMSI
output[p++] = 0xe4;
output[p++] = 0xa1;
output[p++] = 0x80;
count --;
count--;
}
int inputPtr = 0; // input[0]
@@ -322,7 +321,7 @@ namespace LibMSI
Console.Error.WriteLine("Too big!");
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
int sz = (int)stm.Size;
byte[] data;
if (sz == 0)
@@ -331,7 +330,7 @@ namespace LibMSI
}
else
{
data = new byte[sz];
data = new byte[sz];
if (stm.Read(sz, data) == null)
{
Console.Error.WriteLine("Read stream failed");
@@ -344,6 +343,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
// TODO: Move to LibmsiDatabase
public static LibmsiResult WriteStreamData(LibmsiDatabase db, string stname, byte[] data, int sz)
{
if (db.Outfile == null)
@@ -369,7 +369,8 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
public static int MsiTableGetRowSize(LibmsiDatabase db, LibmsiColumnInfo[] cols, int count, int bytes_per_strref)
// TODO: Move to LibmsiDatabase
public static int GetRowSize(LibmsiColumnInfo[] cols, int count, int bytes_per_strref)
{
if (count == 0)
return 0;
@@ -379,21 +380,23 @@ namespace LibMSI
int size = 0;
for (int i = 0; i < count; i++)
{
size += BytesPerColumn(db, cols[i], bytes_per_strref);
size += BytesPerColumn(cols[i], bytes_per_strref);
}
return size;
}
LibmsiColumnInfo last_col = cols[count - 1];
return last_col.Offset + BytesPerColumn(db, last_col, bytes_per_strref);
return last_col.Offset + BytesPerColumn(last_col, bytes_per_strref);
}
// TODO: Move to LibmsiDatabase
public static void FreeCachedTables(LibmsiDatabase db)
{
db.Tables.Clear();
}
// TODO: Move to LibmsiDatabase
public static LibmsiResult OpenTable(LibmsiDatabase db, string name, bool encoded)
{
string decname = null;
@@ -418,6 +421,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
// TODO: Move to LibmsiDatabase
public static LibmsiResult GetTable(LibmsiDatabase db, string name, out LibmsiTable table_ret)
{
table_ret = null;
@@ -467,7 +471,8 @@ namespace LibMSI
return ret;
}
public static LibmsiResult MsiCreateTable(LibmsiDatabase db, string name, column_info col_info, LibmsiCondition persistent)
// TODO: Move to LibmsiDatabase
public static LibmsiResult CreateTable(LibmsiDatabase db, string name, column_info col_info, LibmsiCondition persistent)
{
StringPersistence string_persistence = (persistent != LibmsiCondition.LIBMSI_CONDITION_FALSE) ? StringPersistence.StringPersistent : StringPersistence.StringNonPersistent;
int nField;
@@ -493,7 +498,7 @@ namespace LibMSI
};
column_info col = col_info;
for (; col != null; col = col.Next )
for (; col != null; col = col.Next)
{
table.ColCount++;
}
@@ -519,7 +524,7 @@ namespace LibMSI
};
}
TableCalcColumnOffsets(db, table.ColInfo, table.ColCount);
CalcColumnOffsets(table.ColInfo, table.ColCount);
LibmsiResult r = LibmsiTableView.Create(db, szTables, out LibmsiView tv);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
@@ -598,7 +603,8 @@ namespace LibMSI
return r;
}
public static void MsiUpdateTableColumns(LibmsiDatabase db, string name)
// TODO: Move to LibmsiDatabase
public static void UpdateTableColumns(LibmsiDatabase db, string name)
{
LibmsiTable table = FindCachedTable(db, name);
int old_count = table.ColCount;
@@ -611,7 +617,7 @@ namespace LibMSI
if (table.ColCount == 0)
return;
int size = MsiTableGetRowSize(db, table.ColInfo, table.ColCount, LONG_STR_BYTES);
int size = GetRowSize(table.ColInfo, table.ColCount, LONG_STR_BYTES);
int offset = table.ColInfo[table.ColCount - 1].Offset;
for (int n = 0; n < table.RowCount; n++)
@@ -633,13 +639,14 @@ namespace LibMSI
/// <summary>
/// Try to find the table name in the _Tables table
/// </summary>
// TODO: Move to LibmsiDatabase
public static bool TableViewExists(LibmsiDatabase db, string name)
{
if (name == szTables || name == szColumns || name == szStreams || name == szStorages)
return true;
LibmsiResult r = db.Strings.IdFromStringUTF8(name, out int table_id);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS )
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return false;
r = GetTable(db, szTables, out LibmsiTable table);
@@ -649,7 +656,7 @@ namespace LibMSI
return false;
}
for (int i = 0; i < table.RowCount; i++ )
for (int i = 0; i < table.RowCount; i++)
{
if (ReadTableInt(table.Data, i, 0, LONG_STR_BYTES) == table_id)
return true;
@@ -658,6 +665,7 @@ namespace LibMSI
return false;
}
// TODO: Move to LibmsiDatabase
public static LibmsiResult AddStream(LibmsiDatabase db, string name, GsfInput data)
{
LibmsiRecord rec = LibmsiRecord.Create(2);
@@ -667,16 +675,17 @@ namespace LibMSI
if (!rec.SetString(1, name))
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
LibmsiResult r = RecordSetGsfInput(rec, 2, data);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS )
LibmsiResult r = rec.SetGsfInput(2, data);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
string insert = "INSERT INTO `_Streams`(`Name`, `Data`) VALUES (?, ?)";
Exception err = null;
LibmsiQuery query = LibmsiQuery.Create(db, insert, ref err);
return QueryExecute(query, rec);
return query.Execute(rec);
}
// TODO: Move to LibmsiDatabase
public static LibmsiResult DatabseCommitTables(LibmsiDatabase db, int bytes_per_strref)
{
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_SUCCESS;
@@ -706,6 +715,7 @@ namespace LibMSI
return r;
}
// TODO: Move to LibmsiDatabase
public static LibmsiCondition IsTablePersistent(LibmsiDatabase db, string table)
{
if (table == null)
@@ -718,17 +728,18 @@ namespace LibMSI
return t.Persistent;
}
public static LibmsiResult MsiTableFindRow(LibmsiTableView tv, LibmsiRecord rec, out int row, out int column)
// TODO: Move to LibmsiTableView
public static LibmsiResult FindRow(LibmsiTableView tv, LibmsiRecord rec, out int row, out int column)
{
row = 0; column = 0;
int[] data = MsiRecordToRow(tv, rec);
int[] data = RecordToRow(tv, rec);
if (data == null)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
for (int i = 0; i < tv.Table.RowCount; i++)
{
r = MsiRowMatches(tv, i, data, out column);
r = RowMatches(tv, i, data, out column);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
row = i;
@@ -742,7 +753,8 @@ namespace LibMSI
/// <summary>
/// Enumerate the table transforms in a transform storage and apply each one.
/// </summary>
public static LibmsiResult MsiTableApplyTransform(LibmsiDatabase db, GsfInfile stg)
// TODO: Move to LibmsiDatabase
public static LibmsiResult ApplyTransform(LibmsiDatabase db, GsfInfile stg)
{
TRANSFORMDATA tables = null, columns = null;
LibmsiResult ret = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
@@ -795,11 +807,11 @@ namespace LibMSI
// Apply _Tables and _Columns transforms first so that
// the table metadata is correct, and empty tables exist.
ret = MsiTableLoadTransform( db, stg, strings, tables, bytes_per_strref);
ret = LoadTransform(db, stg, strings, tables, bytes_per_strref);
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS && ret != LibmsiResult.LIBMSI_RESULT_INVALID_TABLE)
goto end;
ret = MsiTableLoadTransform( db, stg, strings, columns, bytes_per_strref );
ret = LoadTransform(db, stg, strings, columns, bytes_per_strref);
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS && ret != LibmsiResult.LIBMSI_RESULT_INVALID_TABLE)
goto end;
@@ -808,7 +820,7 @@ namespace LibMSI
foreach (TRANSFORMDATA transform in transforms)
{
if (transform.Name == szColumns && transform.Name == szTables && ret == LibmsiResult.LIBMSI_RESULT_SUCCESS)
ret = MsiTableLoadTransform(db, stg, strings, transform, bytes_per_strref);
ret = LoadTransform(db, stg, strings, transform, bytes_per_strref);
}
transforms.Clear();
@@ -816,7 +828,7 @@ namespace LibMSI
if (ret == LibmsiResult.LIBMSI_RESULT_SUCCESS)
db.AppendStorageToDb(stg);
end:
end:
if (strings != null)
strings.Destroy();
@@ -829,12 +841,12 @@ namespace LibMSI
private static int Utf2Mime(int x)
{
if ((x >= '0') && ( x <= '9'))
if ((x >= '0') && (x <= '9'))
return x - '0';
if ((x >= 'A') && (x <= 'Z'))
return x - 'A' + 10;
if ((x >= 'a') && (x <= 'z'))
return x- 'a' + 10 + 26;
return x - 'a' + 10 + 26;
if (x == '.')
return 10 + 26 + 26;
if (x == '_')
@@ -850,7 +862,7 @@ namespace LibMSI
return x - 10 + 'A';
if (x < (10 + 26 + 26))
return x - 10 - 26 + 'a';
if (x == ( 10 + 26 + 26))
if (x == (10 + 26 + 26))
return '.';
return '_';
}
@@ -858,10 +870,11 @@ namespace LibMSI
/// <summary>
/// Add this table to the list of cached tables in the database
/// </summary>
// TODO: Move to LibmsiDatabase
private static LibmsiResult ReadTableFromStorage(LibmsiDatabase db, LibmsiTable t, GsfInfile stg)
{
int row_size = MsiTableGetRowSize(db, t.ColInfo, t.ColCount, db.BytesPerStrref);
int row_size_mem = MsiTableGetRowSize(db, t.ColInfo, t.ColCount, LONG_STR_BYTES);
int row_size = GetRowSize(t.ColInfo, t.ColCount, db.BytesPerStrref);
int row_size_mem = GetRowSize(t.ColInfo, t.ColCount, LONG_STR_BYTES);
// If we can't read the table, just assume that it's empty
ReadStreamData(stg, t.Name, out byte[] rawdata, out int rawsize);
@@ -888,8 +901,8 @@ namespace LibMSI
for (int j = 0; j < t.ColCount; j++)
{
int m = BytesPerColumn( db, t.ColInfo[j], LONG_STR_BYTES);
int n = BytesPerColumn( db, t.ColInfo[j], db.BytesPerStrref);
int m = BytesPerColumn(t.ColInfo[j], LONG_STR_BYTES);
int n = BytesPerColumn(t.ColInfo[j], db.BytesPerStrref);
if (n != 2 && n != 3 && n != 4)
{
@@ -924,6 +937,7 @@ namespace LibMSI
}
// TODO: Move this to the correct section
// TODO: Move to LibmsiDatabase
public static LibmsiTable FindCachedTable(LibmsiDatabase db, string name)
{
foreach (LibmsiTable t in db.Tables)
@@ -935,19 +949,20 @@ namespace LibMSI
return null;
}
private static void TableCalcColumnOffsets(LibmsiDatabase db, LibmsiColumnInfo[] colinfo, int count)
private static void CalcColumnOffsets(LibmsiColumnInfo[] colinfo, int count)
{
for (int i = 0; colinfo[i] != null && i < count; i++)
{
//assert(i + 1 == colinfo[i].number);
if (i != 0)
colinfo[i].Offset = colinfo[i - 1].Offset + BytesPerColumn( db, colinfo[i - 1], LONG_STR_BYTES);
colinfo[i].Offset = colinfo[i - 1].Offset + BytesPerColumn(colinfo[i - 1], LONG_STR_BYTES);
else
colinfo[i].Offset = 0;
}
}
private static LibmsiResult GetDefaultTableColumns(LibmsiDatabase db, string name, LibmsiColumnInfo[] colinfo, ref int sz)
// TODO: Move to LibmsiDatabase
private static LibmsiResult GetDefaultTableColumns(string name, LibmsiColumnInfo[] colinfo, ref int sz)
{
LibmsiColumnInfo[] p;
int n;
@@ -977,11 +992,12 @@ namespace LibMSI
break;
}
TableCalcColumnOffsets(db, colinfo, n);
CalcColumnOffsets(colinfo, n);
sz = n;
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
// TODO: Move to LibmsiDatabase
private static LibmsiResult TableGetColumnInfo(LibmsiDatabase db, string name, out LibmsiColumnInfo[] pcols, out int pcount)
{
pcols = null; pcount = 0;
@@ -1007,17 +1023,18 @@ namespace LibMSI
return r;
}
// TODO: Move to LibmsiDatabase
private static LibmsiResult GetTableColumns(LibmsiDatabase db, string szTableName, LibmsiColumnInfo[] colinfo, ref int sz)
{
int maxcount = sz;
int n = 0;
// First check if there is a default table with that name
LibmsiResult r = GetDefaultTableColumns(db, szTableName, colinfo, ref sz);
LibmsiResult r = GetDefaultTableColumns(szTableName, colinfo, ref sz);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS && sz != 0)
return r;
r = GetTable( db, szColumns, out LibmsiTable table);
r = GetTable(db, szColumns, out LibmsiTable table);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
Console.Error.WriteLine("Couldn't load _Columns table");
@@ -1081,11 +1098,12 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
TableCalcColumnOffsets(db, colinfo, n);
CalcColumnOffsets(colinfo, n);
sz = n;
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
// TODO: Move to LibmsiDatabase
private static LibmsiResult SaveTable(LibmsiDatabase db, LibmsiTable t, int bytes_per_strref)
{
// Nothing to do for non-persistent tables
@@ -1098,7 +1116,7 @@ namespace LibMSI
if (t.RowCount == 0 && t.Name != szTables)
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
int row_size = MsiTableGetRowSize(db, t.ColInfo, t.ColCount, bytes_per_strref);
int row_size = GetRowSize(t.ColInfo, t.ColCount, bytes_per_strref);
int row_count = t.RowCount;
for (int i = 0; i < t.RowCount; i++)
{
@@ -1122,8 +1140,8 @@ namespace LibMSI
for (int j = 0; j < t.ColCount; j++)
{
int m = BytesPerColumn(db, t.ColInfo[j], LONG_STR_BYTES);
int n = BytesPerColumn(db, t.ColInfo[j], bytes_per_strref);
int m = BytesPerColumn(t.ColInfo[j], LONG_STR_BYTES);
int n = BytesPerColumn(t.ColInfo[j], bytes_per_strref);
if (n != 2 && n != 3 && n != 4)
{
@@ -1167,7 +1185,8 @@ namespace LibMSI
return ret;
}
private static LibmsiResult MsiRecordEncodedStreamName(LibmsiTableView tv, LibmsiRecord rec, out string pstname)
// TODO: Move to LibmsiTableView
private static LibmsiResult RecordEncodedStreamName(LibmsiTableView tv, LibmsiRecord rec, out string pstname)
{
int len = tv.Name.Length + 1;
string stname = tv.Name + '\0';
@@ -1177,7 +1196,7 @@ namespace LibMSI
{
if ((tv.Columns[i].Type & MSITYPE_KEY) != 0)
{
string sval = MsiDupRecordField(rec, i + 1 );
string sval = rec.DupRecordField(i + 1);
if (sval == null)
{
r = LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
@@ -1201,7 +1220,8 @@ namespace LibMSI
return r;
}
private static LibmsiRecord MsiGetTransformRecord(LibmsiTableView tv, StringTable st, GsfInfile stg, byte[] rawdata, int bytes_per_strref)
// TODO: Move to LibmsiTableView
private static LibmsiRecord GetTransformRecord(LibmsiTableView tv, StringTable st, GsfInfile stg, byte[] rawdata, int bytes_per_strref)
{
int val, ofs = 0;
LibmsiColumnInfo[] columns = tv.Columns;
@@ -1226,9 +1246,9 @@ namespace LibMSI
{
GsfInput stm = null;
ofs += BytesPerColumn(tv.Database, columns[i], bytes_per_strref);
ofs += BytesPerColumn(columns[i], bytes_per_strref);
LibmsiResult r = MsiRecordEncodedStreamName(tv, rec, out string encname);
LibmsiResult r = RecordEncodedStreamName(tv, rec, out string encname);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return null;
@@ -1237,9 +1257,9 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return null;
RecordLoadStream(rec, i + 1, stm);
rec.LoadStream(i + 1, stm);
}
else if((columns[i].Type & MSITYPE_STRING) != 0)
else if ((columns[i].Type & MSITYPE_STRING) != 0)
{
val = ReadRawInt(rawdata, ofs, bytes_per_strref);
string sval = st.LookupId(val);
@@ -1248,13 +1268,13 @@ namespace LibMSI
}
else
{
int n = BytesPerColumn(tv.Database, columns[i], bytes_per_strref);
switch( n )
int n = BytesPerColumn(columns[i], bytes_per_strref);
switch (n)
{
case 2:
val = ReadRawInt(rawdata, ofs, n);
if (val != 0)
rec.SetInt(i + 1, val - 0x8000 );
rec.SetInt(i + 1, val - 0x8000);
break;
case 4:
@@ -1275,6 +1295,7 @@ namespace LibMSI
return rec;
}
// TODO: Move to LibmsiRecord
private static void DumpRecord(LibmsiRecord rec)
{
int n = rec.GetFieldCount();
@@ -1283,35 +1304,37 @@ namespace LibMSI
string sval;
if (rec.IsNull(i))
{
//TRACE("row . []");
Console.WriteLine("row . []");
}
else if ((sval = RecordGetStringRaw( rec, i )) != null)
else if ((sval = rec.GetStringRaw(i)) != null)
{
//TRACE($"row . [{sval}]");
Console.WriteLine($"row . [{sval}]");
}
else
{
//TRACE($"row . [0x{rec.GetInt(i):8x}]");
Console.WriteLine($"row . [0x{rec.GetInt(i):8x}]");
}
}
}
// TODO: Move to StringTable
private static void DumpTable(StringTable st, ushort[] rawdata, int rawsize)
{
for(int i = 0; i < (rawsize / 2); i++)
for (int i = 0; i < (rawsize / 2); i++)
{
string sval = st.LookupId(rawdata[i]);
//TRACE($" {rawdata[i]:4x} {sval}");
Console.WriteLine($" {rawdata[i]:4x} {sval}");
}
}
private static int[] MsiRecordToRow(LibmsiTableView tv, LibmsiRecord rec)
// TODO: Move to LibmsiTableView
private static int[] RecordToRow(LibmsiTableView tv, LibmsiRecord rec)
{
string str;
LibmsiResult r;
int[] data = new int[tv.NumCols];
for(int i = 0; i < tv.NumCols; i++ )
for (int i = 0; i < tv.NumCols; i++)
{
data[i] = 0;
@@ -1321,7 +1344,7 @@ namespace LibMSI
// Turn the transform column value into a row value
if ((tv.Columns[i].Type & MSITYPE_STRING) != 0 && !MSITYPE_IS_BINARY(tv.Columns[i].Type))
{
str = RecordGetStringRaw(rec, i + 1);
str = rec.GetStringRaw(i + 1);
if (str != null)
{
r = tv.Database.Strings.IdFromStringUTF8(str, out data[i]);
@@ -1351,7 +1374,8 @@ namespace LibMSI
return data;
}
private static LibmsiResult MsiRowMatches(LibmsiTableView tv, int row, int[] data, out int column)
// TODO: Move to LibmsiTableView
private static LibmsiResult RowMatches(LibmsiTableView tv, int row, int[] data, out int column)
{
column = 0;
@@ -1383,7 +1407,8 @@ namespace LibMSI
return ret;
}
private static LibmsiResult MsiTableLoadTransform(LibmsiDatabase db, GsfInfile stg, StringTable st, TRANSFORMDATA transform, int bytes_per_strref)
// TODO: Move to LibmsiDatabase
private static LibmsiResult LoadTransform(LibmsiDatabase db, GsfInfile stg, StringTable st, TRANSFORMDATA transform, int bytes_per_strref)
{
int i, colcol = 0;
@@ -1444,7 +1469,7 @@ namespace LibMSI
if ((tv.Columns[i].Type & MSITYPE_STRING) != 0 && !MSITYPE_IS_BINARY(tv.Columns[i].Type))
sz += bytes_per_strref;
else
sz += BytesPerColumn(tv.Database, tv.Columns[i], bytes_per_strref);
sz += BytesPerColumn(tv.Columns[i], bytes_per_strref);
}
}
else
@@ -1465,7 +1490,7 @@ namespace LibMSI
if ((tv.Columns[i].Type & MSITYPE_STRING) != 0 && !MSITYPE_IS_BINARY(tv.Columns[i].Type))
sz += bytes_per_strref;
else
sz += BytesPerColumn(tv.Database, tv.Columns[i], bytes_per_strref);
sz += BytesPerColumn(tv.Columns[i], bytes_per_strref);
}
}
}
@@ -1474,11 +1499,11 @@ namespace LibMSI
if (n + sz > rawsize)
{
Console.Error.WriteLine("Borked.");
DumpTable(st, rawdata.Cast<ushort>().ToArray(), rawsize );
DumpTable(st, rawdata.Cast<ushort>().ToArray(), rawsize);
break;
}
LibmsiRecord rec = MsiGetTransformRecord( tv, st, stg, rawdata.Skip(n).ToArray(), bytes_per_strref );
LibmsiRecord rec = GetTransformRecord(tv, st, stg, rawdata.Skip(n).ToArray(), bytes_per_strref);
if (rec != null)
{
string table = string.Empty;
@@ -1489,7 +1514,7 @@ namespace LibMSI
if (name == szColumns)
{
int tablesz = 32;
RecordGetString(rec, 1, out table, ref tablesz);
rec.GetString(1, out table, ref tablesz);
number = rec.GetInt(2);
// Native msi seems writes nul into the Number (2nd) column of
@@ -1512,7 +1537,7 @@ namespace LibMSI
if (TRACE_ON)
DumpRecord(rec);
r = MsiTableFindRow(tv, rec, out row, out _);
r = FindRow(tv, rec, out row, out _);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
if (mask == 0)
@@ -1536,13 +1561,13 @@ namespace LibMSI
}
else
{
r = tv.InsertRow(rec, -1, false );
r = tv.InsertRow(rec, -1, false);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
Console.Error.WriteLine($"Failed to insert row {r}");
}
if (number != LIBMSI_NULL_INT && name == szColumns)
MsiUpdateTableColumns(db, table);
UpdateTableColumns(db, table);
}
n += sz;

View File

@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
namespace LibMSI
namespace LibMSI.Internal
{
#region Enums
@@ -51,7 +51,7 @@ namespace LibMSI
#region Delegates
public delegate LibmsiResult record_func(LibmsiRecord record, object o);
internal delegate LibmsiResult record_func(LibmsiRecord record, object o);
#endregion

View File

@@ -23,10 +23,10 @@
using System;
using System.Text;
using LibGSF.Input;
using static LibMSI.LibmsiTable;
using static LibMSI.MsiPriv;
using static LibMSI.Internal.LibmsiTable;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Internal
{
internal class msistring
{

View File

@@ -18,7 +18,7 @@
using System.Linq;
namespace LibMSI
namespace LibMSI.Internal
{
/// <summary>
/// The token value for this keyword

View File

@@ -25,12 +25,14 @@ using System.Linq;
using System.Text;
using LibGSF.Input;
using LibGSF.Output;
using LibMSI.Internal;
using LibMSI.Views;
using static LibMSI.LibmsiQuery;
using static LibMSI.LibmsiRecord;
using static LibMSI.LibmsiSummaryInfo;
using static LibMSI.LibmsiTable;
using static LibMSI.MsiPriv;
using static LibMSI.StringTable;
using static LibMSI.Internal.LibmsiTable;
using static LibMSI.Internal.MsiPriv;
using static LibMSI.Internal.StringTable;
namespace LibMSI
{
@@ -69,7 +71,7 @@ namespace LibMSI
internal static readonly byte[] clsid_msi_transform = { 0x82, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
internal static readonly byte[] clsid_msi_database = { 0x84, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
internal static readonly byte[] clsid_msi_patch = { 0x86, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
#endregion
@@ -301,7 +303,7 @@ namespace LibMSI
if (error != null)
return false;
LibmsiResult r = ImportImpl(path);
LibmsiResult r = Import(path);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
error = new Exception($"LIBMSI_RESULT_ERROR: {r}");
@@ -376,7 +378,7 @@ namespace LibMSI
if (conflicts)
r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
done:
done:
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
error = new Exception($"LIBMSI_RESULT_ERROR: {r}");
@@ -403,14 +405,14 @@ namespace LibMSI
return r == LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
r = MsiEnumDbStorages(CommitStorage, this);
r = EnumDbStorages(CommitStorage, this);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
error = new Exception($"Failed to save storages r={r}");
return r == LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
r = MsiEnumDbStreams(CommitStream, this);
r = EnumDbStreams(CommitStream, this);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
error = new Exception($"Failed to save streams r={r}");
@@ -441,7 +443,7 @@ namespace LibMSI
#region Internal Functions
internal LibmsiResult MsiOpenStorage(string stname)
internal LibmsiResult OpenStorage(string stname)
{
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_NOT_ENOUGH_MEMORY;
foreach (LibmsiStorage stg in Storages)
@@ -465,7 +467,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal LibmsiResult MsiCreateStorage(string stname, GsfInput stm)
internal LibmsiResult CreateStorage(string stname, GsfInput stm)
{
if (Flags.HasFlag(LibmsiDbFlags.LIBMSI_DB_FLAGS_READONLY))
return LibmsiResult.LIBMSI_RESULT_ACCESS_DENIED;
@@ -498,7 +500,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal void MsiDestroyStorage(string stname)
internal void DestroyStorage(string stname)
{
foreach (LibmsiStorage storage in Storages)
{
@@ -522,7 +524,7 @@ namespace LibMSI
{
if (stname == stream.Name)
{
MsiDestroyStream(stname);
DestroyStream(stname);
break;
}
}
@@ -537,7 +539,7 @@ namespace LibMSI
return ret;
}
internal LibmsiResult MsiCreateStream(string stname, GsfInput stm)
internal LibmsiResult CreateStream(string stname, GsfInput stm)
{
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
bool found = false;
@@ -564,7 +566,7 @@ namespace LibMSI
return r;
}
internal LibmsiResult MsiEnumDbStreams(Func<string, GsfInput, object, LibmsiResult> fn, object opaque)
internal LibmsiResult EnumDbStreams(Func<string, GsfInput, object, LibmsiResult> fn, object opaque)
{
foreach (LibmsiStream stream in Streams)
{
@@ -577,7 +579,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal LibmsiResult MsiEnumDbStorages(Func<string, GsfInfile, object, LibmsiResult> fn, object opaque)
internal LibmsiResult EnumDbStorages(Func<string, GsfInfile, object, LibmsiResult> fn, object opaque)
{
foreach (LibmsiStorage storage in Storages)
{
@@ -590,14 +592,14 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal LibmsiResult MsiGetRawStream(string stname , out GsfInput stm)
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;
LibmsiResult ret = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
foreach(LibmsiTransform transform in Transforms)
foreach (LibmsiTransform transform in Transforms)
{
Exception err = null;
stm = transform.Stg.ChildByName(stname, ref err);
@@ -611,7 +613,7 @@ namespace LibMSI
return ret;
}
internal void MsiDestroyStream(string stname)
internal void DestroyStream(string stname)
{
foreach (LibmsiStream stream in Streams)
{
@@ -715,7 +717,7 @@ namespace LibMSI
internal LibmsiResult Open()
{
byte[] uuid = new byte [16];
byte[] uuid = new byte[16];
LibmsiResult ret = LibmsiResult.LIBMSI_RESULT_OPEN_FAILED;
Exception err = null;
@@ -795,7 +797,7 @@ namespace LibMSI
if (TRACE_ON && stg != null)
EnumStreamNames(stg);
ret = MsiTableApplyTransform(this, stg);
ret = LibmsiTable.ApplyTransform(this, stg);
end:
return ret;
@@ -809,7 +811,7 @@ namespace LibMSI
string sql = $"select * from `_Columns` where `Table` = '{table}'";
LibmsiResult r = QueryOpen(this, out LibmsiQuery query, sql);
if( r != LibmsiResult.LIBMSI_RESULT_SUCCESS )
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
// Count the number of primary key records
@@ -820,7 +822,7 @@ namespace LibMSI
};
int count = 0;
r = QueryIterateRecords(query, ref count, MsiPrimaryKeyIterator, info);
r = query.IterateRecords(ref count, PrimaryKeyIterator, info);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
// Allocate a record and fill in the names of the tables
@@ -828,8 +830,8 @@ namespace LibMSI
info.N = 0;
count = 0;
r = QueryIterateRecords(query, ref count, MsiPrimaryKeyIterator, info);
if( r == LibmsiResult.LIBMSI_RESULT_SUCCESS )
r = query.IterateRecords(ref count, PrimaryKeyIterator, info);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
prec = info.Rec;
}
@@ -888,7 +890,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
private string MsiReadTextArchive(string path, out int len)
private string ReadTextArchive(string path, out int len)
{
try
{
@@ -903,7 +905,7 @@ namespace LibMSI
}
}
private void MsiParseLine(ref string line, ref int linePtr, out string[] entries, out int num_entries, ref int len)
private void ParseLine(ref string line, ref int linePtr, out string[] entries, out int num_entries, ref int len)
{
int ptr = linePtr;
int save;
@@ -987,9 +989,9 @@ namespace LibMSI
num_entries = count;
}
private string MsiBuildCreateSQLPrelude(string table) => $"CREATE TABLE `{table}` (";
private string BuildCreateSQLPrelude(string table) => $"CREATE TABLE `{table}` (";
private string MsiBuildCreateSQLColumns(string[] columns_data, string[] types, int num_columns)
private string BuildCreateSQLColumns(string[] columns_data, string[] types, int num_columns)
{
int sql_size = 1;
long len;
@@ -1002,12 +1004,12 @@ namespace LibMSI
comma = "\0";
else
comma = ",";
comma += '\0';
int ptr = 1; // types[i][1];
len = long.Parse(new string(types[i].Skip(1).SkipWhile(c => char.IsWhiteSpace(c)).TakeWhile(c => c == '+' || c == '-' || char.IsDigit(c)).ToArray()));
string extra = "\0";
string type = null;
string size = "\0";
@@ -1096,17 +1098,17 @@ namespace LibMSI
return columns;
}
private string MsiBuildCreateSQLPostlude(string[] primary_keys, int num_keys)
private string BuildCreateSQLPostlude(string[] primary_keys, int num_keys)
{
string keys = string.Join(", ", primary_keys.Select(s => $"`{s}`"));
return $"PRIMARY KEY {keys})";
}
private LibmsiResult MsiAddTableToDb(string[] columns, string[] types, string[] labels, int num_labels, int num_columns)
private LibmsiResult AddTableToDb(string[] columns, string[] types, string[] labels, int num_labels, int num_columns)
{
string prelude = MsiBuildCreateSQLPrelude(labels[0]);
string columns_sql = MsiBuildCreateSQLColumns(columns, types, num_columns);
string postlude = MsiBuildCreateSQLPostlude(labels.Skip(1).ToArray(), num_labels - 1); // Skip over table name
string prelude = BuildCreateSQLPrelude(labels[0]);
string columns_sql = BuildCreateSQLColumns(columns, types, num_columns);
string postlude = BuildCreateSQLPostlude(labels.Skip(1).ToArray(), num_labels - 1); // Skip over table name
if (prelude == null || columns_sql == null || postlude == null)
return LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
@@ -1125,7 +1127,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
}
LibmsiResult r = QueryExecute(view, null);
LibmsiResult r = view.Execute(null);
view.Close(ref error);
if (error != null)
Console.Error.WriteLine(error.Message);
@@ -1141,19 +1143,24 @@ namespace LibMSI
{
switch (types[i][0])
{
case 'L': case 'l': case 'S': case 's':
case 'L':
case 'l':
case 'S':
case 's':
rec.SetString(i + 1, data[i]);
break;
case 'I': case 'i':
case 'I':
case 'i':
if (data[i] != null)
rec.SetInt(i + 1, int.Parse(new string(data[i].Skip(1).SkipWhile(c => char.IsWhiteSpace(c)).TakeWhile(c => c == '+' || c == '-' || char.IsDigit(c)).ToArray())));
break;
case 'V': case 'v':
case 'V':
case 'v':
if (data[i] != null)
{
string file = System.IO.Path.Combine(name, data[i]);
LibmsiResult r = RecordLoadStreamFromFile(rec, i + 1, file);
LibmsiResult r = rec.LoadStreamFromFile(i + 1, file);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
@@ -1169,7 +1176,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
private LibmsiResult MsiAddRecordsToTable(string[] columns, string[] types, string[] labels, string[][] records, int num_columns, int num_records)
private LibmsiResult AddRecordsToTable(string[] columns, string[] types, string[] labels, string[][] records, int num_columns, int num_records)
{
LibmsiResult r = LibmsiTableView.Create(this, labels[0], out LibmsiView view);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
@@ -1202,7 +1209,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
private LibmsiResult ImportImpl(string path)
private LibmsiResult Import(string path)
{
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
int num_records = 0;
@@ -1210,14 +1217,14 @@ namespace LibMSI
string suminfo = "_SummaryInformation";
string forcecodepage = "_ForceCodepage";
string data = MsiReadTextArchive(path, out int len);
string data = ReadTextArchive(path, out int len);
if (data == null)
return LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
int ptr = 0; // data[0]
MsiParseLine(ref data, ref ptr, out string[] columns, out int num_columns, ref len);
MsiParseLine(ref data, ref ptr, out string[] types, out int num_types, ref len);
MsiParseLine(ref data, ref ptr, out string[] labels, out int num_labels, ref len);
ParseLine(ref data, ref ptr, out string[] columns, out int num_columns, ref len);
ParseLine(ref data, ref ptr, out string[] types, out int num_types, ref len);
ParseLine(ref data, ref ptr, out string[] labels, out int num_labels, ref len);
if (num_columns == 1 && columns[0][0] == '\0' && num_labels == 1 && labels[0][0] == '\0' && num_types == 2 && types[1] == forcecodepage)
return Strings.SetCodePage(int.Parse(new string(types[0].Skip(1).SkipWhile(c => char.IsWhiteSpace(c)).TakeWhile(c => c == '+' || c == '-' || char.IsDigit(c)).ToArray())));
@@ -1230,14 +1237,14 @@ namespace LibMSI
// Read in the table records
while (len != 0)
{
MsiParseLine(ref data, ref ptr, out string[] record, out _, ref len);
ParseLine(ref data, ref ptr, out string[] record, out _, ref len);
records.Add(record);
}
if (labels[0] == suminfo)
{
r = MsiAddSumInfo(this, records.ToArray(), num_records, num_columns);
r = AddSummaryInfo(this, records.ToArray(), num_records, num_columns);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
@@ -1245,18 +1252,18 @@ namespace LibMSI
{
if (!TableViewExists(this, labels[0]))
{
r = MsiAddTableToDb(columns, types, labels, num_labels, num_columns);
r = AddTableToDb(columns, types, labels, num_labels, num_columns);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
r = MsiAddRecordsToTable(columns, types, labels, records.ToArray(), num_columns, num_records);
r = AddRecordsToTable(columns, types, labels, records.ToArray(), num_columns, num_records);
}
return r;
}
private static bool MsiExportStream(GsfInput gsfin, string table_dir, out string str, ref Exception error)
private static bool ExportStream(GsfInput gsfin, string table_dir, out string str, ref Exception error)
{
str = null;
if (table_dir == null)
@@ -1292,16 +1299,16 @@ namespace LibMSI
}
}
private static LibmsiResult MsiExportRecord(Stream fd, LibmsiRecord row, int start, string table_dir, ref Exception error)
private static LibmsiResult ExportRecord(Stream fd, LibmsiRecord row, int start, string table_dir, ref Exception error)
{
int count = row.GetFieldCount();
for (int i = start; i <= count; i++)
{
string str;
RecordGetGsfInput(row, i, out GsfInput input);
row.GetGsfInput(i, out GsfInput input);
if (input != null)
{
if (!MsiExportStream(input, table_dir, out str, ref error))
if (!ExportStream(input, table_dir, out str, ref error))
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
input = null;
@@ -1330,16 +1337,17 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
private static LibmsiResult MsiExportRow(LibmsiRecord row, object arg)
// TODO: Move to LibmsiRecord
private static LibmsiResult ExportRowImpl(LibmsiRecord row, object arg)
{
ExportRow export = arg as ExportRow;
Exception err = export.Error;
LibmsiResult r = MsiExportRecord(export.FD, row, 1, export.TableDir, ref err);
LibmsiResult r = ExportRecord(export.FD, row, 1, export.TableDir, ref err);
export.Error = err;
return r;
}
private static LibmsiResult MsiExportForceCodePage(Stream fd, int codepage)
private static LibmsiResult ExportForceCodePage(Stream fd, int codepage)
{
string data = $"\r\n\r\n{codepage}\t_ForceCodepage\r\n\0";
int sz = data.Length;
@@ -1354,7 +1362,7 @@ namespace LibMSI
}
}
private LibmsiResult MsiExportSummaryInfo(Stream fd, ref Exception error)
private LibmsiResult ExportSummaryInfo(Stream fd, ref Exception error)
{
LibmsiSummaryInfo si = LibmsiSummaryInfo.Create(this, 0, ref error);
if (si == null)
@@ -1376,7 +1384,7 @@ namespace LibMSI
{
if (si.Property[i].VariantType != LibmsiOLEVariantType.OLEVT_EMPTY)
{
string val = SummaryInfoAsString(si, i);
string val = si.SummaryInfoAsString(i);
if (val == null)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
@@ -1401,11 +1409,11 @@ namespace LibMSI
if (table == "_ForceCodepage")
{
int codepage = Strings.GetCodePage();
return MsiExportForceCodePage(fd, codepage);
return ExportForceCodePage(fd, codepage);
}
else if (table == "_SummaryInformation")
{
return MsiExportSummaryInfo(fd, ref error);
return ExportSummaryInfo(fd, ref error);
}
string query = $"select * from {table}";
@@ -1413,21 +1421,21 @@ namespace LibMSI
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
// Write out row 1, the column names
r = QueryGetColumnInfo(view, LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord rec);
r = view.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord rec);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
MsiExportRecord(fd, rec, 1, null, ref error);
ExportRecord(fd, rec, 1, null, ref error);
// Write out row 2, the column types
r = QueryGetColumnInfo(view, LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out rec);
r = view.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out rec);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
MsiExportRecord(fd, rec, 1, null, ref error);
ExportRecord(fd, rec, 1, null, ref error);
// Write out row 3, the table name + keys
r = GetPrimaryKeys(table, out rec);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
rec.SetString(0, table);
MsiExportRecord(fd, rec, 0, null, ref error);
ExportRecord(fd, rec, 0, null, ref error);
}
// Write out row 4 onwards, the data
@@ -1439,7 +1447,7 @@ namespace LibMSI
};
int count = 0;
r = QueryIterateRecords(view, ref count, MsiExportRow, export);
r = view.IterateRecords(ref count, ExportRowImpl, export);
}
return r;
@@ -1458,43 +1466,42 @@ namespace LibMSI
return type1 == type2;
}
// TODO: Move to LibmsiQuery
private static LibmsiResult MergeVerifyColnames(LibmsiQuery dbview, LibmsiQuery mergeview)
{
LibmsiResult r = QueryGetColumnInfo(dbview, LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord dbrec);
LibmsiResult r = dbview.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord dbrec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
r = QueryGetColumnInfo(mergeview, LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord mergerec);
r = mergeview.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord mergerec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
int count = dbrec.GetFieldCount();
for (int i = 1; i <= count; i++)
{
if (RecordGetStringRaw(mergerec, i) == null)
if (mergerec.GetStringRaw(i) == null)
break;
if (RecordGetStringRaw(dbrec, i) != RecordGetStringRaw(mergerec, i))
if (dbrec.GetStringRaw(i) != mergerec.GetStringRaw(i))
return LibmsiResult.LIBMSI_RESULT_DATATYPE_MISMATCH;
}
dbrec = mergerec = null;
r = QueryGetColumnInfo(dbview, LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out dbrec);
r = dbview.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out dbrec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
r = QueryGetColumnInfo(mergeview, LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out mergerec);
r = mergeview.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out mergerec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
count = dbrec.GetFieldCount();
for (int i = 1; i <= count; i++)
{
if (RecordGetStringRaw(mergerec, i) == null)
if (mergerec.GetStringRaw(i) == null)
break;
if (!MergeTypeMatch(RecordGetStringRaw(dbrec, i), RecordGetStringRaw(mergerec, i)))
if (!MergeTypeMatch(dbrec.GetStringRaw(i), mergerec.GetStringRaw(i)))
{
r = LibmsiResult.LIBMSI_RESULT_DATATYPE_MISMATCH;
break;
@@ -1520,16 +1527,17 @@ namespace LibMSI
for (int i = 1; i <= count; i++)
{
if (RecordGetStringRaw(dbrec, i) != RecordGetStringRaw(mergerec, i))
if (dbrec.GetStringRaw(i) != mergerec.GetStringRaw(i))
return LibmsiResult.LIBMSI_RESULT_DATATYPE_MISMATCH;
}
return r;
}
// TODO: Move to LibmsiRecord
private static string GetKeyValue(LibmsiQuery view, string key, LibmsiRecord rec)
{
LibmsiResult r = QueryGetColumnInfo(view, LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord colnames);
LibmsiResult r = view.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord colnames);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return null;
@@ -1537,7 +1545,7 @@ namespace LibMSI
bool cmp;
do
{
string temp = MsiDupRecordField(colnames, ++i);
string temp = colnames.DupRecordField(++i);
cmp = (key == temp);
} while (!cmp);
@@ -1545,17 +1553,17 @@ namespace LibMSI
string str;
// Quote string record fields
if (RecordGetStringRaw(rec, i) != null)
str = $"{RecordGetStringRaw(rec, i)}";
if (rec.GetStringRaw(i) != null)
str = $"{rec.GetStringRaw(i)}";
else
str = rec.GetString(i);
return str;
}
private static string CreateDiffRowQuery(LibmsiDatabase merge, LibmsiQuery view, string table, LibmsiRecord rec)
private string CreateDiffRowQuery(LibmsiQuery view, string table, LibmsiRecord rec)
{
LibmsiResult r = merge.GetPrimaryKeys(table, out LibmsiRecord keys);
LibmsiResult r = GetPrimaryKeys(table, out LibmsiRecord keys);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return null;
@@ -1563,7 +1571,7 @@ namespace LibMSI
int count = keys.GetFieldCount();
for (int i = 1; i <= count; i++)
{
string key = RecordGetStringRaw(keys, i);
string key = keys.GetStringRaw(i);
string val = GetKeyValue(view, key, rec);
if (i == count)
@@ -1575,6 +1583,7 @@ namespace LibMSI
return query;
}
// TODO: Move to LibmsiRecord
private static LibmsiResult MergeDiffRow(LibmsiRecord rec, object param)
{
MERGEDATA data = param as MERGEDATA;
@@ -1585,7 +1594,7 @@ namespace LibMSI
if (TableViewExists(data.Database, table.Name))
{
string query = CreateDiffRowQuery(data.Merge, data.CurView, table.Name, rec);
string query = data.Merge.CreateDiffRowQuery(data.CurView, table.Name, rec);
if (query == null)
return LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
@@ -1596,11 +1605,11 @@ namespace LibMSI
return r;
}
r = QueryExecute(dbview, null);
r = dbview.Execute(null);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
r = QueryFetch(dbview, out LibmsiRecord row);
r = dbview.Fetch(out LibmsiRecord row);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS && !RecordCompare(rec, row))
{
table.NumConflicts++;
@@ -1615,18 +1624,18 @@ namespace LibMSI
}
mergerow = new MERGEROW();
mergerow.Data = RecordClone(rec);
mergerow.Data = rec.Clone();
if (mergerow.Data == null)
{
r = LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
return r;
return r;
}
table.Rows.AddFirst(mergerow);
return r;
}
private LibmsiResult MsiGetTableLabels(string table, out string[] labels, out int numlabels)
private LibmsiResult GetTableLabels(string table, out string[] labels, out int numlabels)
{
labels = null; numlabels = 0;
LibmsiResult r = GetPrimaryKeys(table, out LibmsiRecord prec);
@@ -1640,16 +1649,17 @@ namespace LibMSI
labels[0] = table;
for (int i = 1; i <= count; i++)
{
labels[i] = RecordGetStringRaw(prec, i);
labels[i] = prec.GetStringRaw(i);
}
return r;
}
private static LibmsiResult MsiGetQueryColumns(LibmsiQuery query, out string[] columns, out int numcolumns)
// TODO: Move to LibmsiRecord
private static LibmsiResult GetQueryColumns(LibmsiQuery query, out string[] columns, out int numcolumns)
{
columns = null; numcolumns = 0;
LibmsiResult r = QueryGetColumnInfo(query, LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord prec);
LibmsiResult r = query.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_NAMES, out LibmsiRecord prec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
@@ -1658,17 +1668,18 @@ namespace LibMSI
for (int i = 1; i <= count; i++)
{
columns[i - 1] = RecordGetStringRaw(prec, i);
columns[i - 1] = prec.GetStringRaw(i);
}
numcolumns = count;
return r;
}
private static LibmsiResult MsiGetQueryTypes(LibmsiQuery query, out string[] types, out int numtypes)
// TODO: Move to LibmsiRecord
private static LibmsiResult GetQueryTypes(LibmsiQuery query, out string[] types, out int numtypes)
{
types = null; numtypes = 0;
LibmsiResult r = QueryGetColumnInfo(query, LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out LibmsiRecord prec);
LibmsiResult r = query.GetColumnInfo(LibmsiColInfo.LIBMSI_COL_INFO_TYPES, out LibmsiRecord prec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
@@ -1677,12 +1688,13 @@ namespace LibMSI
numtypes = count;
for (int i = 1; i <= count; i++)
{
types[i - 1] = RecordGetStringRaw(prec, i);
types[i - 1] = prec.GetStringRaw(i);
}
return r;
}
// TODO: Move to MERGETABLE
private static void FreeMergeTable(MERGETABLE table)
{
table.Labels = null;
@@ -1692,10 +1704,10 @@ namespace LibMSI
table.Rows.Clear();
}
private LibmsiResult MsiGetMergeTable(string name, out MERGETABLE ptable)
private LibmsiResult GetMergeTable(string name, out MERGETABLE ptable)
{
MERGETABLE table = new MERGETABLE();
LibmsiResult r = MsiGetTableLabels(name, out string[] labels, out int num_labels);
LibmsiResult r = GetTableLabels(name, out string[] labels, out int num_labels);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
goto err;
@@ -1707,14 +1719,14 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
goto err;
r = MsiGetQueryColumns(mergeview, out string[] columns, out int num_columns);
r = GetQueryColumns(mergeview, out string[] columns, out int num_columns);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
goto err;
table.Columns = columns;
table.NumColumns = num_columns;
r = MsiGetQueryTypes(mergeview, out string[] types, out int num_types);
r = GetQueryTypes(mergeview, out string[] types, out int num_types);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
goto err;
@@ -1735,10 +1747,11 @@ namespace LibMSI
return r;
}
// TODO: Move to LibmsiRecord
private static LibmsiResult MergeDiffTables(LibmsiRecord rec, object param)
{
MERGEDATA data = param as MERGEDATA;
string name = RecordGetStringRaw(rec, 1);
string name = rec.GetStringRaw(1);
string query = $"SELECT * FROM {name}";
LibmsiResult r = QueryOpen(data.Merge, out LibmsiQuery mergeview, query);
@@ -1760,7 +1773,7 @@ namespace LibMSI
return r;
}
r = data.Merge.MsiGetMergeTable(name, out MERGETABLE table);
r = data.Merge.GetMergeTable(name, out MERGETABLE table);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
@@ -1768,7 +1781,7 @@ namespace LibMSI
data.CurView = mergeview;
int count = 0;
r = QueryIterateRecords(mergeview, ref count, MergeDiffRow, data);
r = mergeview.IterateRecords(ref count, MergeDiffRow, data);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
FreeMergeTable(table);
@@ -1796,7 +1809,7 @@ namespace LibMSI
data.TableData.AddFirst(tabledata);
int count = 0;
r = QueryIterateRecords(view, ref count, MergeDiffTables, data);
r = view.IterateRecords(ref count, MergeDiffTables, data);
return r;
}
@@ -1805,7 +1818,7 @@ namespace LibMSI
LibmsiResult r;
if (!TableViewExists(this, table.Name))
{
r = MsiAddTableToDb(table.Columns, table.Types, table.Labels, table.NumLabels, table.NumColumns);
r = AddTableToDb(table.Columns, table.Types, table.Labels, table.NumLabels, table.NumColumns);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
@@ -1831,12 +1844,12 @@ namespace LibMSI
LibmsiResult r;
if (!TableViewExists(this, error))
{
string create = $"CREATE TABLE `{error}` (`Table` CHAR(255) NOT NULL, `NumRowMergeConflicts` SHORT NOT NULL PRIMARY KEY `Table`)";
string create = $"CREATE TABLE `{error}` (`Table` CHAR(255) NOT NULL, `NumRowMergeConflicts` SHORT NOT NULL PRIMARY KEY `Table`)";
r = QueryOpen(this, out LibmsiQuery createView, create);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
r = QueryExecute(createView, null);
r = createView.Execute(null);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
}
@@ -1846,7 +1859,7 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
r = QueryExecute(view, null);
r = view.Execute(null);
return r;
}
@@ -1891,7 +1904,7 @@ namespace LibMSI
}
else
{
MsiOpenStorage(name);
OpenStorage(name);
}
}
}
@@ -1921,6 +1934,7 @@ namespace LibMSI
return true;
}
// TODO: Can we avoid the use of `opaque`?
private static LibmsiResult CommitStorage(string name, GsfInfile stg, object opaque)
{
LibmsiDatabase db = opaque as LibmsiDatabase;
@@ -1938,6 +1952,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
// TODO: Can we avoid the use of `opaque`?
private static LibmsiResult CommitStream(string name, GsfInput stm, object opaque)
{
LibmsiDatabase db = opaque as LibmsiDatabase;
@@ -1958,7 +1973,8 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
private static LibmsiResult MsiPrimaryKeyIterator(LibmsiRecord rec, object param)
// TODO: Can we avoid the use of `param`?
private static LibmsiResult PrimaryKeyIterator(LibmsiRecord rec, object param)
{
MsiPrimaryKeyRecordInfo info = param as MsiPrimaryKeyRecordInfo;
int type = rec.GetInt(4);
@@ -1969,11 +1985,11 @@ namespace LibMSI
{
if (info.N == 1)
{
string table = RecordGetStringRaw(rec, 1);
string table = rec.GetStringRaw(1);
info.Rec.SetString(0, table);
}
string name = RecordGetStringRaw(rec, 3);
string name = rec.GetStringRaw(3);
info.Rec.SetString(info.N, name);
}
}

View File

@@ -21,8 +21,10 @@
using System;
using System.Collections.Generic;
using LibGSF.Input;
using LibMSI.Internal;
using LibMSI.Views;
using static LibMSI.LibmsiRecord;
using static LibMSI.MsiPriv;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
{
@@ -103,7 +105,7 @@ namespace LibMSI
if (error != null)
return null;
LibmsiResult ret = QueryFetch(this, out LibmsiRecord record);
LibmsiResult ret = Fetch(out LibmsiRecord record);
// FIXME: raise error when it happens
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS && ret != LibmsiResult.NO_MORE_ITEMS)
@@ -123,7 +125,7 @@ namespace LibMSI
if (error != null)
return false;
LibmsiResult ret = QueryExecute(this, rec);
LibmsiResult ret = Execute(rec);
// FIXME: raise error when it happens
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS)
@@ -193,7 +195,7 @@ namespace LibMSI
if (error != null)
return null;
LibmsiResult r = QueryGetColumnInfo(this, info,out LibmsiRecord rec);
LibmsiResult r = GetColumnInfo(info, out LibmsiRecord rec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
error = new Exception($"LIBMSI_RESULT_ERROR: {r}");
@@ -204,6 +206,7 @@ namespace LibMSI
#region Internal Functions
// TODO: Move to LibmsiView
internal static LibmsiResult ViewFindColumn(LibmsiView table, string name, string table_name, out int n)
{
n = 0;
@@ -214,14 +217,14 @@ namespace LibMSI
for (int i = 1; i <= count; i++)
{
r = table.GetColumnInfo(i, out string col_name, out _, out _, out string haystack_table_name);
if( r != LibmsiResult.LIBMSI_RESULT_SUCCESS )
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
bool x = name == col_name;
if (table_name != null)
x |= table_name == haystack_table_name;
if( !x )
if (!x)
{
n = i;
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
@@ -231,6 +234,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER;
}
// TODO: Move to LibmsiDatabase
internal static LibmsiResult DatabaseOpenQuery(LibmsiDatabase db, string szQuery, out LibmsiQuery pView)
{
Exception err = null;
@@ -238,8 +242,9 @@ namespace LibMSI
return pView != null ? LibmsiResult.LIBMSI_RESULT_SUCCESS : LibmsiResult.LIBMSI_RESULT_BAD_QUERY_SYNTAX;
}
// TODO: Move to LibmsiDatabase
internal static LibmsiResult QueryOpen(LibmsiDatabase db, out LibmsiQuery view, string query)
{
{
Exception err = null;
view = LibmsiQuery.Create(db, query, ref err);
if (err != null)
@@ -248,9 +253,9 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal static LibmsiResult QueryIterateRecords(LibmsiQuery view, ref int count, record_func func, object param)
internal LibmsiResult IterateRecords(ref int count, record_func func, object param)
{
LibmsiResult r = QueryExecute(view, null);
LibmsiResult r = Execute(null);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
@@ -262,19 +267,19 @@ namespace LibMSI
int n = 0;
for (; (max == 0) || (n < max); n++)
{
r = QueryFetch(view, out LibmsiRecord rec);
r = Fetch(out LibmsiRecord rec);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
break;
if (func != null)
r = func( rec, param );
r = func(rec, param);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
break;
}
Exception error = null; // FIXME: move error handling to caller
view.Close(ref error);
Close(ref error);
if (error != null)
Console.Error.WriteLine(error);
@@ -288,20 +293,21 @@ namespace LibMSI
/// <summary>
/// Return a single record from a query
/// </summary>
// TODO: Move to LibmsiDatabase
internal static LibmsiRecord QueryGetRecord(LibmsiDatabase db, string query)
{
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_SUCCESS;
Exception error = null; // FIXME: move error to caller
LibmsiQuery view = LibmsiQuery.Create(db, query, ref error);
LibmsiQuery view = Create(db, query, ref error);
if (error != null)
r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
error = null;
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
QueryExecute(view, null);
QueryFetch(view, out LibmsiRecord rec);
view.Execute(null);
view.Fetch(out LibmsiRecord rec);
view.Close(ref error);
if (error != null)
Console.Error.WriteLine(error);
@@ -312,6 +318,7 @@ namespace LibMSI
return null;
}
// TODO: Move to LibmsiDatabase
internal static LibmsiResult MsiViewGetRow(LibmsiDatabase db, LibmsiView view, int row, out LibmsiRecord rec)
{
rec = null;
@@ -380,31 +387,28 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal static LibmsiResult QueryFetch(LibmsiQuery query, out LibmsiRecord prec)
internal LibmsiResult Fetch(out LibmsiRecord prec)
{
prec = null;
LibmsiView view = query.View;
if (view == null)
if (View == null)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
LibmsiResult r = MsiViewGetRow(query.Database, view, query.Row, out prec);
LibmsiResult r = MsiViewGetRow(Database, View, Row, out prec);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
query.Row++;
Row++;
return r;
}
internal static LibmsiResult QueryExecute(LibmsiQuery query, LibmsiRecord rec)
internal LibmsiResult Execute(LibmsiRecord rec)
{
LibmsiView view = query.View;
if (view == null)
if (View == null)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
query.Row = 0;
Row = 0;
try
{
return view.Execute(rec);
return View.Execute(rec);
}
catch
{
@@ -412,19 +416,18 @@ namespace LibMSI
}
}
internal static LibmsiResult QueryGetColumnInfo(LibmsiQuery query, LibmsiColInfo info, out LibmsiRecord prec)
internal LibmsiResult GetColumnInfo(LibmsiColInfo info, out LibmsiRecord prec)
{
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
LibmsiView view = query.View;
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
prec = null;
if (view == null)
if (View == null)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
int count;
try
{
r = view.GetDimensions(out _, out count);
r = View.GetDimensions(out _, out count);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
}
@@ -440,16 +443,16 @@ namespace LibMSI
if (rec == null)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
for (int i = 0; i < count; i++ )
for (int i = 0; i < count; i++)
{
r = view.GetColumnInfo(i + 1, out string name, out int type, out bool temporary, out _);
if( r != LibmsiResult.LIBMSI_RESULT_SUCCESS )
r = View.GetColumnInfo(i + 1, out string name, out int type, out bool temporary, out _);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
continue;
if (info == LibmsiColInfo.LIBMSI_COL_INFO_NAMES)
rec.SetString(i + 1, name);
else
MsiSetRecordTypeString(rec, i+1, type, temporary);
SetRecordTypeString(rec, i + 1, type, temporary);
}
prec = rec;
@@ -471,7 +474,8 @@ namespace LibMSI
return r == LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
private static void MsiSetRecordTypeString(LibmsiRecord rec, int field, int type, bool temporary)
// TODO: Move to LibmsiRecord
private static void SetRecordTypeString(LibmsiRecord rec, int field, int type, bool temporary)
{
string szType;
if (MSITYPE_IS_BINARY(type))

View File

@@ -21,6 +21,7 @@
using System;
using System.IO;
using LibGSF.Input;
using LibMSI.Internal;
using static LibMSI.LibmsiTypes;
namespace LibMSI
@@ -234,7 +235,7 @@ namespace LibMSI
/// <returns>True on success.</returns>
public bool LoadStream(int field, string szFilename)
{
LibmsiResult ret = RecordLoadStreamFromFile(this, field, szFilename);
LibmsiResult ret = LoadStreamFromFile(field, szFilename);
return ret == LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
@@ -258,13 +259,13 @@ namespace LibMSI
return false;
byte[] data = new byte[count];
int bytes_read = input.Read(data, 0, count);
if (bytes_read != count)
return false;
GsfInput stm = GsfInputMemory.Create(data, count, true);
if (RecordLoadStream(this, field, stm) != LibmsiResult.LIBMSI_RESULT_SUCCESS)
if (LoadStream(field, stm) != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return false;
return true;
@@ -278,7 +279,7 @@ namespace LibMSI
public Stream GetStream(int field)
{
Exception err = null;
GsfInput stm = RecordGetStream(this, field, ref err);
GsfInput stm = GetStream(field, ref err);
if (stm == null)
return null;
@@ -289,17 +290,17 @@ namespace LibMSI
#region Internal Functions
internal static LibmsiResult RecordCopyField(LibmsiRecord in_rec, int in_n, LibmsiRecord out_rec, int out_n)
internal LibmsiResult CopyField(int in_n, LibmsiRecord out_rec, int out_n)
{
LibmsiResult r = LibmsiResult.LIBMSI_RESULT_SUCCESS;
if (in_n > in_rec.Count || out_n > out_rec.Count)
if (in_n > Count || out_n > out_rec.Count)
{
r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
else if (in_rec != out_rec || in_n != out_n)
{
LibmsiField input = in_rec.Fields[in_n];
else if (this != out_rec || in_n != out_n)
{
LibmsiField input = Fields[in_n];
LibmsiField output = out_rec.Fields[out_n];
switch (input.Type)
@@ -327,20 +328,20 @@ namespace LibMSI
return r;
}
internal static string RecordGetStringRaw(LibmsiRecord rec, int field)
internal string GetStringRaw(int field)
{
if (field > rec.Count)
if (field > Count)
return null;
if (rec.Fields[field].Type != LIBMSI_FIELD_TYPE_STR )
if (Fields[field].Type != LIBMSI_FIELD_TYPE_STR)
return null;
return rec.Fields[field].szVal;
return Fields[field].szVal;
}
internal static LibmsiResult RecordGetString(LibmsiRecord rec, int field, out string szValue, ref int pcchValue)
internal LibmsiResult GetString(int field, out string szValue, ref int pcchValue)
{
if (field > rec.Count)
if (field > Count)
{
if (pcchValue > 0)
szValue = "\0";
@@ -352,15 +353,15 @@ namespace LibMSI
}
int len;
switch (rec.Fields[field].Type)
switch (Fields[field].Type)
{
case LIBMSI_FIELD_TYPE_INT:
szValue = rec.Fields[field].iVal.ToString();
szValue = Fields[field].iVal.ToString();
len = szValue.Length;
break;
case LIBMSI_FIELD_TYPE_STR:
szValue = rec.Fields[field].szVal;
len = rec.Fields[field].szVal.Length;
szValue = Fields[field].szVal;
len = Fields[field].szVal.Length;
break;
case LIBMSI_FIELD_TYPE_NULL:
if (pcchValue > 0)
@@ -385,32 +386,32 @@ namespace LibMSI
return ret;
}
internal static LibmsiResult RecordLoadStream(LibmsiRecord rec, int field, GsfInput stream)
internal LibmsiResult LoadStream(int field, GsfInput stream)
{
if ((field == 0) || (field > rec.Count))
if ((field == 0) || (field > Count))
return LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER;
rec.Fields[field].Type = LIBMSI_FIELD_TYPE_STREAM;
rec.Fields[field].Stream = stream;
Fields[field].Type = LIBMSI_FIELD_TYPE_STREAM;
Fields[field].Stream = stream;
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal static LibmsiResult RecordLoadStreamFromFile(LibmsiRecord rec, int field, string szFilename)
internal LibmsiResult LoadStreamFromFile(int field, string szFilename)
{
GsfInput stm;
LibmsiResult r;
if ((field == 0) || (field > rec.Count) )
if ((field == 0) || (field > Count))
return LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER;
// No filename means we should seek back to the start of the stream
if (szFilename == null)
{
if (rec.Fields[field].Type != LIBMSI_FIELD_TYPE_STREAM)
if (Fields[field].Type != LIBMSI_FIELD_TYPE_STREAM)
return LibmsiResult.LIBMSI_RESULT_INVALID_FIELD;
stm = rec.Fields[field].Stream;
stm = Fields[field].Stream;
if (stm == null)
return LibmsiResult.LIBMSI_RESULT_INVALID_FIELD;
@@ -424,50 +425,50 @@ namespace LibMSI
return r;
// If all's good, store it in the record
RecordLoadStream(rec, field, stm);
LoadStream(field, stm);
}
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal static LibmsiResult RecordSetGsfInput(LibmsiRecord rec, int field, GsfInput stm)
internal LibmsiResult SetGsfInput(int field, GsfInput stm)
{
if (field > rec.Count )
if (field > Count)
return LibmsiResult.LIBMSI_RESULT_INVALID_FIELD;
rec.Fields[field].Type = LIBMSI_FIELD_TYPE_STREAM;
rec.Fields[field].Stream = stm;
Fields[field].Type = LIBMSI_FIELD_TYPE_STREAM;
Fields[field].Stream = stm;
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal static LibmsiResult RecordGetGsfInput(LibmsiRecord rec, int field, out GsfInput pstm)
internal LibmsiResult GetGsfInput(int field, out GsfInput pstm)
{
pstm = null;
if (field > rec.Count )
if (field > Count)
return LibmsiResult.LIBMSI_RESULT_INVALID_FIELD;
if (rec.Fields[field].Type != LIBMSI_FIELD_TYPE_STREAM)
if (Fields[field].Type != LIBMSI_FIELD_TYPE_STREAM)
return LibmsiResult.LIBMSI_RESULT_INVALID_FIELD;
pstm = rec.Fields[field].Stream;
pstm = Fields[field].Stream;
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
internal static LibmsiRecord RecordClone(LibmsiRecord rec)
internal LibmsiRecord Clone()
{
int count = rec.GetFieldCount();
LibmsiRecord clone = LibmsiRecord.Create(count);
int count = GetFieldCount();
LibmsiRecord clone = Create(count);
if (clone == null)
return null;
for (int i = 0; i <= count; i++)
{
if (rec.Fields[i].Type == LIBMSI_FIELD_TYPE_STREAM)
if (Fields[i].Type == LIBMSI_FIELD_TYPE_STREAM)
{
Exception err = null;
GsfInput stm = rec.Fields[i].Stream.Duplicate(ref err);
GsfInput stm = Fields[i].Stream.Duplicate(ref err);
if (stm == null)
return null;
@@ -476,7 +477,7 @@ namespace LibMSI
}
else
{
LibmsiResult r = RecordCopyField(rec, i, clone, i);
LibmsiResult r = CopyField(i, clone, i);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return null;
}
@@ -521,18 +522,18 @@ namespace LibMSI
return true;
}
internal static string MsiDupRecordField(LibmsiRecord rec, int field)
internal string DupRecordField(int field)
{
if (rec.IsNull(field))
if (IsNull(field))
return null;
int sz = 0;
LibmsiResult r = RecordGetString(rec, field, out _, ref sz);
LibmsiResult r = GetString(field, out _, ref sz);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return null;
sz++;
r = RecordGetString(rec, field, out string str, ref sz);
r = GetString(field, out string str, ref sz);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
Console.Error.WriteLine("Failed to get string!");
@@ -554,12 +555,12 @@ namespace LibMSI
int p = 0; // str[0]
// Skip the minus sign
if (str[p] == '-' )
if (str[p] == '-')
p++;
while (p < str.Length && str[p] != '\0')
{
if( (str[p] < '0') || (str[p] > '9') )
if ((str[p] < '0') || (str[p] > '9'))
return false;
x *= 10;
@@ -571,7 +572,7 @@ namespace LibMSI
if (str[0] == '-')
x = -x;
output = x;
output = x;
return true;
}
@@ -609,28 +610,27 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
private static GsfInput RecordGetStream(LibmsiRecord rec, int field, ref Exception error)
private GsfInput GetStream(int field, ref Exception error)
{
if (field > rec.Count)
if (field > Count)
{
error = new Exception($"LIBMSI_RESULT_ERROR: {LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER}");
return null;
}
if (rec.Fields[field].Type == LIBMSI_FIELD_TYPE_NULL)
if (Fields[field].Type == LIBMSI_FIELD_TYPE_NULL)
{
error = new Exception($"LIBMSI_RESULT_ERROR: {LibmsiResult.LIBMSI_RESULT_INVALID_DATA}");
return null;
}
if (rec.Fields[field].Type != LIBMSI_FIELD_TYPE_STREAM)
if (Fields[field].Type != LIBMSI_FIELD_TYPE_STREAM)
{
error = new Exception($"LIBMSI_RESULT_ERROR: {LibmsiResult.LIBMSI_RESULT_INVALID_DATATYPE}");
return null;
}
GsfInput stm = rec.Fields[field].Stream;
GsfInput stm = Fields[field].Stream;
if (stm == null)
{
error = new Exception($"LIBMSI_RESULT_ERROR: {LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER}");

View File

@@ -23,7 +23,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using LibGSF.Input;
using static LibMSI.MsiPriv;
using LibMSI.Internal;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
{
@@ -116,9 +117,9 @@ namespace LibMSI
// Read the stream... if we fail, we'll start with an empty property set
if (self.Database != null)
{
LibmsiResult r = self.Database.MsiGetRawStream(szSumInfo, out GsfInput stm);
LibmsiResult r = self.Database.GetRawStream(szSumInfo, out GsfInput stm);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
LoadSummaryInfo(self, stm);
self.LoadSummaryInfo(stm);
}
return self;
@@ -179,7 +180,7 @@ namespace LibMSI
if (error != null)
return null;
SummaryInfoGetProperty(this, prop, out LibmsiPropertyType type, out _, out _, out _, out _, out string val, ref error);
GetProperty(prop, out LibmsiPropertyType type, out _, out _, out _, out _, out string val, ref error);
return val;
}
@@ -191,7 +192,7 @@ namespace LibMSI
if (error != null)
return -1;
SummaryInfoGetProperty(this, prop, out LibmsiPropertyType type, out int val, out _, out _, out _, out _, ref error);
GetProperty(prop, out LibmsiPropertyType type, out int val, out _, out _, out _, out _, ref error);
return val;
}
@@ -203,7 +204,7 @@ namespace LibMSI
if (error != null)
return 0;
SummaryInfoGetProperty(this, prop, out LibmsiPropertyType type, out _, out ulong val, out _, out _, out _, ref error);
GetProperty(prop, out LibmsiPropertyType type, out _, out ulong val, out _, out _, out _, ref error);
return val;
}
@@ -225,7 +226,7 @@ namespace LibMSI
return false;
}
LibmsiResult ret = SummaryInfoSetProperty(this, prop, LibmsiOLEVariantType.OLEVT_LPSTR, 0, 0, value);
LibmsiResult ret = SetProperty(prop, LibmsiOLEVariantType.OLEVT_LPSTR, 0, 0, value);
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
error = new Exception($"LIBMSI_RESULT_ERROR: {ret}");
@@ -254,7 +255,7 @@ namespace LibMSI
return false;
}
LibmsiResult ret = SummaryInfoSetProperty(this, prop, type, value, 0, null);
LibmsiResult ret = SetProperty(prop, type, value, 0, null);
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
error = new Exception($"LIBMSI_RESULT_ERROR: {ret}");
@@ -282,7 +283,7 @@ namespace LibMSI
return false;
}
LibmsiResult ret = SummaryInfoSetProperty(this, prop, LibmsiOLEVariantType.OLEVT_FILETIME, 0, value, null);
LibmsiResult ret = SetProperty(prop, LibmsiOLEVariantType.OLEVT_FILETIME, 0, value, null);
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
error = new Exception($"LIBMSI_RESULT_ERROR: {ret}");
@@ -308,7 +309,7 @@ namespace LibMSI
return false;
}
LibmsiResult ret = SumInfoPersist(this, Database);
LibmsiResult ret = Persist(Database);
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS)
error = new Exception($"LIBMSI_RESULT_ERROR: {ret}");
@@ -328,7 +329,7 @@ namespace LibMSI
if (error != null)
return false;
LibmsiResult ret = SumInfoPersist(this, db);
LibmsiResult ret = Persist(db);
if (ret != LibmsiResult.LIBMSI_RESULT_SUCCESS)
error = new Exception($"LIBMSI_RESULT_ERROR: {ret}");
@@ -352,9 +353,9 @@ namespace LibMSI
#region Internal Functions
internal static string SummaryInfoAsString(LibmsiSummaryInfo si, int uiProperty)
internal string SummaryInfoAsString(int uiProperty)
{
LibmsiOLEVariant prop = si.Property[uiProperty];
LibmsiOLEVariant prop = Property[uiProperty];
switch (prop.VariantType)
{
@@ -375,10 +376,11 @@ namespace LibMSI
return null;
}
internal static LibmsiResult MsiAddSumInfo(LibmsiDatabase db, string[][] records, int num_records, int num_columns)
// TODO: Move to LibmsiDatabase
internal static LibmsiResult AddSummaryInfo(LibmsiDatabase db, string[][] records, int num_records, int num_columns)
{
Exception err = null;
LibmsiSummaryInfo si = LibmsiSummaryInfo.Create(db, num_records * (num_columns / 2), ref err);
LibmsiSummaryInfo si = Create(db, num_records * (num_columns / 2), ref err);
if (si == null)
{
Console.Error.WriteLine("No summary information!");
@@ -394,19 +396,20 @@ namespace LibMSI
return r;
//assert(GetType(pid) != LibmsiOLEVariantType.OLEVT_EMPTY);
r = SummaryInfoSetProperty(si, pid, GetType(pid), int_value, ft_value, str_value);
r = si.SetProperty(pid, GetType(pid), int_value, ft_value, str_value);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
}
}
return SumInfoPersist(si, db);
return si.Persist(db);
}
#endregion
#region Utilities
// TODO: Move to LibmsiOLEVariant
private static void FreeProp(LibmsiOLEVariant prop)
{
prop.VariantType = LibmsiOLEVariantType.OLEVT_EMPTY;
@@ -589,7 +592,7 @@ namespace LibMSI
{
// No-op
}
else if( proptype == LibmsiOLEVariantType.OLEVT_LPSTR)
else if (proptype == LibmsiOLEVariantType.OLEVT_LPSTR)
{
if (str == null)
return;
@@ -622,7 +625,7 @@ namespace LibMSI
}
}
private static LibmsiResult LoadSummaryInfo(LibmsiSummaryInfo si, GsfInput stm)
private LibmsiResult LoadSummaryInfo(GsfInput stm)
{
long sz = stm.Size;
if (sz == 0)
@@ -650,7 +653,7 @@ namespace LibMSI
// Seek to the location of the section
ofs += 16;
int dwOffset = (int)ReadDWORD(data, ref ofs);
// Read the section itself
ofs = dwOffset;
int cbSection = (int)ReadDWORD(data, ref ofs);
@@ -663,7 +666,7 @@ namespace LibMSI
}
// Read all the data in one go
ReadPropertiesFromData(si.Property, data.Skip(dwOffset).ToArray(), cbSection, cProperties);
ReadPropertiesFromData(Property, data.Skip(dwOffset).ToArray(), cbSection, cProperties);
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
@@ -708,6 +711,7 @@ namespace LibMSI
return (7 + len) & ~3;
}
// TODO: Move to LibmsiOLEVariant
private static int WritePropertyToData(LibmsiOLEVariant prop, byte[] data, int ofs)
{
int sz = ofs;
@@ -716,7 +720,7 @@ namespace LibMSI
// Add the type
sz += WriteDWORD(data, sz, (uint)prop.VariantType);
switch( prop.VariantType )
switch (prop.VariantType)
{
case LibmsiOLEVariantType.OLEVT_I2:
case LibmsiOLEVariantType.OLEVT_I4:
@@ -739,14 +743,14 @@ namespace LibMSI
return sz;
}
private static LibmsiResult SumInfoPersist(LibmsiSummaryInfo si, LibmsiDatabase database)
private LibmsiResult Persist(LibmsiDatabase database)
{
// Add up how much space the data will take and calculate the offsets
int cProperties = GetPropertyCount(si.Property);
int cProperties = GetPropertyCount(Property);
int cbSection = 8 + cProperties * 8;
for (int i = 0; i < MSI_MAX_PROPS; i++)
{
cbSection += WritePropertyToData(si.Property[i], null, 0);
cbSection += WritePropertyToData(Property[i], null, 0);
}
int sz = 28 + 20 + cbSection;
@@ -775,7 +779,7 @@ namespace LibMSI
int dwOffset = 8 + cProperties * 8;
for (int i = 0; i < MSI_MAX_PROPS; i++)
{
int propsz = WritePropertyToData(si.Property[i], null, 0);
int propsz = WritePropertyToData(Property[i], null, 0);
if (propsz == 0)
continue;
@@ -789,7 +793,7 @@ namespace LibMSI
// Write out the data
for (int i = 0; i < MSI_MAX_PROPS; i++)
{
sz += WritePropertyToData(si.Property[i], data, sz);
sz += WritePropertyToData(Property[i], data, sz);
}
//assert(sz == 28 + 20 + cbSection);
@@ -798,8 +802,7 @@ namespace LibMSI
return r;
}
private static void SummaryInfoGetProperty(
LibmsiSummaryInfo si,
private void GetProperty(
LibmsiProperty uiProperty,
out LibmsiPropertyType puiDataType,
out int pintvalue,
@@ -816,7 +819,7 @@ namespace LibMSI
return;
}
LibmsiOLEVariant prop = si.Property[(int)uiProperty];
LibmsiOLEVariant prop = Property[(int)uiProperty];
LibmsiPropertyType type;
switch (prop.VariantType)
{
@@ -856,13 +859,7 @@ namespace LibMSI
puiDataType = type;
}
private static LibmsiResult SummaryInfoSetProperty(
LibmsiSummaryInfo si,
LibmsiProperty uiProperty,
LibmsiOLEVariantType type,
int intvalue,
ulong pftValue,
string szValue)
private LibmsiResult SetProperty(LibmsiProperty uiProperty, LibmsiOLEVariantType type, int intvalue, ulong pftValue, string szValue)
{
if (type == LibmsiOLEVariantType.OLEVT_LPSTR && szValue == null)
return LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER;
@@ -870,17 +867,17 @@ namespace LibMSI
if (type == LibmsiOLEVariantType.OLEVT_FILETIME && pftValue == 0)
return LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER;
LibmsiOLEVariant prop = si.Property[(int)uiProperty];
LibmsiOLEVariant prop = Property[(int)uiProperty];
if (prop.VariantType == LibmsiOLEVariantType.OLEVT_EMPTY)
{
LibmsiResult ret = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
if (si.UpdateCount == 0)
if (UpdateCount == 0)
return ret;
si.UpdateCount--;
UpdateCount--;
}
else if (prop.VariantType != type )
else if (prop.VariantType != type)
{
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
}
@@ -911,7 +908,7 @@ namespace LibMSI
{
pid = (LibmsiProperty)int.Parse(new string(prop.SkipWhile(c => char.IsWhiteSpace(c)).TakeWhile(c => c == '+' || c == '-' || char.IsDigit(c)).ToArray()));
int_value = 0; ft_value = 0; str_value = null;
switch (pid)
{
case LibmsiProperty.LIBMSI_PROPERTY_CODEPAGE:

View File

@@ -18,10 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
using LibGSF.Input;
using static LibMSI.LibmsiQuery;
using LibGSF.Input;
using static LibMSI.LibmsiQuery;
namespace LibMSI
namespace LibMSI.Views
{
internal class LibmsiAlterView : LibmsiView
{
@@ -162,11 +162,11 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return false;
r = QueryExecute(view, null);
r = view.Execute(null);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
goto done;
r = QueryFetch(view, out LibmsiRecord rec);
r = view.Fetch(out LibmsiRecord rec);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
rec = null;
@@ -195,7 +195,7 @@ namespace LibMSI
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
int count = 0;
r = QueryIterateRecords(view, ref count, CountIter, colnum);
r = view.IterateRecords(ref count, CountIter, colnum);
view = null;
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{

View File

@@ -18,10 +18,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
using static LibMSI.LibmsiTable;
using static LibMSI.MsiPriv;
using LibMSI.Internal;
using static LibMSI.Internal.LibmsiTable;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Views
{
internal class LibmsiCreateView : LibmsiView
{
@@ -107,7 +108,7 @@ namespace LibMSI
if (IsTemp && !Hold)
return LibmsiResult.LIBMSI_RESULT_SUCCESS;
return MsiCreateTable(Database, Name, ColInfo, persist);
return CreateTable(Database, Name, ColInfo, persist);
}
/// <inheritdoc/>

View File

@@ -20,7 +20,7 @@
using LibGSF.Input;
namespace LibMSI
namespace LibMSI.Views
{
/// <summary>
/// Code to delete rows from a table.

View File

@@ -20,7 +20,7 @@
using System;
namespace LibMSI
namespace LibMSI.Views
{
internal class LibmsiDistinctSet
{

View File

@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
namespace LibMSI
namespace LibMSI.Views
{
internal class LibmsiDropView : LibmsiView
{

View File

@@ -20,10 +20,10 @@
using System;
using static LibMSI.LibmsiRecord;
using static LibMSI.LibmsiSQLInput;
using static LibMSI.MsiPriv;
using static LibMSI.Internal.LibmsiSQLInput;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Views
{
internal class LibmsiInsertView : LibmsiView
{

View File

@@ -21,9 +21,9 @@
using LibGSF.Input;
using static LibMSI.LibmsiQuery;
using static LibMSI.LibmsiRecord;
using static LibMSI.MsiPriv;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Views
{
/// <summary>
/// Below is the query interface to a table

View File

@@ -20,10 +20,11 @@
using System;
using LibGSF.Input;
using LibMSI.Internal;
using static LibMSI.LibmsiRecord;
using static LibMSI.MsiPriv;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Views
{
internal class STORAGE
{
@@ -143,7 +144,7 @@ namespace LibMSI
if (row > NumRows)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
LibmsiResult r = RecordGetGsfInput(rec, 2, out GsfInput stm);
LibmsiResult r = GetGsfInput(rec, 2, out GsfInput stm);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
@@ -166,7 +167,7 @@ namespace LibMSI
if (name == null)
return LibmsiResult.LIBMSI_RESULT_OUTOFMEMORY;
Database.MsiCreateStorage(name, stm);
Database.CreateStorage(name, stm);
storage = CreateStorage(name);
if (storage == null)
r = LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
@@ -202,7 +203,7 @@ namespace LibMSI
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
}
Database.MsiDestroyStorage(name);
Database.DestroyStorage(name);
// Shift the remaining rows
for (int i = row + 1; i < NumRows; i++)
@@ -312,7 +313,7 @@ namespace LibMSI
{
MaxStorages = 1;
Storages = new STORAGE[1];
return Database.MsiEnumDbStorages(AddStorageToTable, this);
return Database.EnumDbStorages(AddStorageToTable, this);
}
#endregion

View File

@@ -20,12 +20,13 @@
using System;
using LibGSF.Input;
using LibMSI.Internal;
using static LibMSI.LibmsiQuery;
using static LibMSI.LibmsiRecord;
using static LibMSI.LibmsiTable;
using static LibMSI.MsiPriv;
using static LibMSI.Internal.LibmsiTable;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Views
{
internal class STREAM
{
@@ -118,7 +119,7 @@ namespace LibMSI
if (row > NumRows)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
LibmsiResult r = RecordGetGsfInput(rec, 2, out GsfInput stm);
LibmsiResult r = GetGsfInput(rec, 2, out GsfInput stm);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
@@ -150,7 +151,7 @@ namespace LibMSI
if (stream == null)
return r;
r = Database.MsiCreateStream(name, stm);
r = Database.CreateStream(name, stm);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
Console.Error.WriteLine($"Failed to create stream: {r}");
@@ -196,7 +197,7 @@ namespace LibMSI
}
encname = EncodeStreamName(false, name);
Database.MsiDestroyStream(encname);
Database.DestroyStream(encname);
// Shift the remaining rows
for (int i = row + 1; i < NumRows; i++)
@@ -328,7 +329,7 @@ namespace LibMSI
{
MaxStreams = 1;
Streams = new STREAM[1];
return Database.MsiEnumDbStreams(AddStreamToTable, this);
return Database.EnumDbStreams(AddStreamToTable, this);
}
#endregion

View File

@@ -21,13 +21,14 @@
using System;
using System.Linq;
using LibGSF.Input;
using LibMSI.Internal;
using static LibMSI.LibmsiQuery;
using static LibMSI.LibmsiRecord;
using static LibMSI.LibmsiTable;
using static LibMSI.MsiPriv;
using static LibMSI.LibmsiTypes;
using static LibMSI.Internal.LibmsiTable;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Views
{
internal class LibmsiColumnHashEntry
{
@@ -84,7 +85,7 @@ namespace LibMSI
tv.Database = db;
tv.Columns = tv.Table.ColInfo;
tv.NumCols = tv.Table.ColCount;
tv.RowSize = MsiTableGetRowSize(db, tv.Table.ColInfo, tv.Table.ColCount, LONG_STR_BYTES);
tv.RowSize = GetRowSize(db, tv.Table.ColInfo, tv.Table.ColCount, LONG_STR_BYTES);
tv.Name = name;
view = tv;
@@ -141,7 +142,7 @@ namespace LibMSI
}
string encname = EncodeStreamName(false, full_name);
r = Database.MsiGetRawStream(encname, out stm);
r = Database.GetRawStream(encname, out stm);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
Console.Error.WriteLine($"Fetching stream {full_name}, error = {r}");
@@ -191,7 +192,7 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;
r = RecordGetGsfInput(rec, i + 1, out GsfInput stm);
r = GetGsfInput(rec, i + 1, out GsfInput stm);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
@@ -441,7 +442,7 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
r = MsiTableFindRow(columns as LibmsiTableView, rec, out int row, out _);
r = FindRow(columns as LibmsiTableView, rec, out int row, out _);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
columns.Delete();
@@ -455,7 +456,7 @@ namespace LibMSI
return r;
}
MsiUpdateTableColumns(Database, table);
UpdateTableColumns(Database, table);
columns.Delete();
return r;
}
@@ -504,7 +505,7 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
MsiUpdateTableColumns(Database, table);
UpdateTableColumns(Database, table);
if (!hold)
return r;
@@ -543,7 +544,7 @@ namespace LibMSI
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
return r;
r = MsiTableFindRow((tables as LibmsiTableView), rec, out int row, out _);
r = FindRow((tables as LibmsiTableView), rec, out int row, out _);
if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS)
{
tables.Delete();
@@ -781,7 +782,7 @@ namespace LibMSI
}
// Check there's no duplicate keys
LibmsiResult r = MsiTableFindRow(this, rec, out int row, out column);
LibmsiResult r = FindRow(this, rec, out int row, out column);
if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS)
return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED;

View File

@@ -18,9 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
using static LibMSI.LibmsiRecord;
using LibMSI.Internal;
using static LibMSI.LibmsiRecord;
namespace LibMSI
namespace LibMSI.Views
{
/// <summary>
/// Below is the query interface to a table

View File

@@ -21,8 +21,9 @@
using System;
using LibGSF.Input;
using LibMSI.Internal;
namespace LibMSI
namespace LibMSI.Views
{
internal class column_info
{
@@ -49,7 +50,7 @@ namespace LibMSI
#endregion
#region Functions
#region Virtual Functions
/// <summary>
/// Reads one integer from {row,col} in the table

View File

@@ -22,12 +22,13 @@
using System;
using System.Linq;
using LibGSF.Input;
using LibMSI.Internal;
using static LibMSI.LibmsiQuery;
using static LibMSI.LibmsiRecord;
using static LibMSI.LibmsiSQLInput;
using static LibMSI.MsiPriv;
using static LibMSI.Internal.LibmsiSQLInput;
using static LibMSI.Internal.MsiPriv;
namespace LibMSI
namespace LibMSI.Views
{
internal class LibmsiRowEntry
{