mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-11-15 16:51:49 +00:00
Organize files, clean up formatting, add TODOs
This commit is contained in:
@@ -18,7 +18,7 @@ using System;
|
||||
using System.IO;
|
||||
using LibGSF.Input;
|
||||
|
||||
namespace LibMSI
|
||||
namespace LibMSI.Internal
|
||||
{
|
||||
internal class LibmsiIStream : Stream
|
||||
{
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
using System.Linq;
|
||||
|
||||
namespace LibMSI
|
||||
namespace LibMSI.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// The token value for this keyword
|
||||
246
BurnOutSharp/External/libmsi/LibmsiDatabase.cs
vendored
246
BurnOutSharp/External/libmsi/LibmsiDatabase.cs
vendored
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
76
BurnOutSharp/External/libmsi/LibmsiQuery.cs
vendored
76
BurnOutSharp/External/libmsi/LibmsiQuery.cs
vendored
@@ -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))
|
||||
|
||||
110
BurnOutSharp/External/libmsi/LibmsiRecord.cs
vendored
110
BurnOutSharp/External/libmsi/LibmsiRecord.cs
vendored
@@ -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}");
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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/>
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
using LibGSF.Input;
|
||||
|
||||
namespace LibMSI
|
||||
namespace LibMSI.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Code to delete rows from a table.
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace LibMSI
|
||||
namespace LibMSI.Views
|
||||
{
|
||||
internal class LibmsiDistinctSet
|
||||
{
|
||||
@@ -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
|
||||
{
|
||||
@@ -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
|
||||
{
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
{
|
||||
Reference in New Issue
Block a user