Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix x86 packing issues in System.Data.OleDb #33899

Merged
merged 9 commits into from
Mar 27, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/libraries/System.Data.OleDb/src/DbPropSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ internal int PropertySetCount
}
}

internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset)
internal ItagDBPROP[] GetPropertySet(int index, out Guid propertyset)
{
if ((index < 0) || (PropertySetCount <= index))
{
Expand All @@ -173,7 +173,7 @@ internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset)
}

tagDBPROPSET propset = new tagDBPROPSET();
tagDBPROP[] properties = null;
ItagDBPROP[] properties = null;

bool mustRelease = false;
RuntimeHelpers.PrepareConstrainedRegions();
Expand All @@ -184,10 +184,10 @@ internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset)
Marshal.PtrToStructure(propertySetPtr, propset);
propertyset = propset.guidPropertySet;

properties = new tagDBPROP[propset.cProperties];
properties = new ItagDBPROP[propset.cProperties];
for (int i = 0; i < properties.Length; ++i)
{
properties[i] = new tagDBPROP();
properties[i] = OleDbStructHelpers.CreateTagDbProp();
IntPtr ptr = ADP.IntPtrOffset(propset.rgProperties, i * ODB.SizeOf_tagDBPROP);
Marshal.PtrToStructure(ptr, properties[i]);
}
Expand All @@ -202,7 +202,7 @@ internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset)
return properties;
}

internal void SetPropertySet(int index, Guid propertySet, tagDBPROP[] properties)
internal void SetPropertySet(int index, Guid propertySet, ItagDBPROP[] properties)
{
if ((index < 0) || (PropertySetCount <= index))
{
Expand Down Expand Up @@ -271,9 +271,9 @@ internal void SetPropertySet(int index, Guid propertySet, tagDBPROP[] properties

internal static DBPropSet CreateProperty(Guid propertySet, int propertyId, bool required, object value)
{
tagDBPROP dbprop = new tagDBPROP(propertyId, required, value);
ItagDBPROP dbprop = OleDbStructHelpers.CreateTagDbProp(propertyId, required, value);
DBPropSet propertyset = new DBPropSet(1);
propertyset.SetPropertySet(0, propertySet, new tagDBPROP[1] { dbprop });
propertyset.SetPropertySet(0, propertySet, new ItagDBPROP[1] { dbprop });
return propertyset;
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Data.OleDb/src/OleDbCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ internal object GetPropertyValue(Guid propertySet, int propertyID)
if (null != _icommandText)
{
OleDbHResult hr;
tagDBPROP[] dbprops;
ItagDBPROP[] dbprops;
UnsafeNativeMethods.ICommandProperties icommandProperties = ICommandProperties();

using (PropertyIDSet propidset = new PropertyIDSet(propertySet, propertyID))
Expand Down Expand Up @@ -1329,22 +1329,22 @@ private DBPropSet CommandPropertySets()
{
propSet = new DBPropSet(1);

tagDBPROP[] dbprops = new tagDBPROP[count];
ItagDBPROP[] dbprops = new ItagDBPROP[count];

dbprops[0] = new tagDBPROP(ODB.DBPROP_COMMANDTIMEOUT, false, CommandTimeout);
dbprops[0] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_COMMANDTIMEOUT, false, CommandTimeout);

if (_executeQuery)
{
// 'Microsoft.Jet.OLEDB.4.0' default is DBPROPVAL_AO_SEQUENTIAL
dbprops[1] = new tagDBPROP(ODB.DBPROP_ACCESSORDER, false, ODB.DBPROPVAL_AO_RANDOM);
dbprops[1] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_ACCESSORDER, false, ODB.DBPROPVAL_AO_RANDOM);

if (keyInfo)
{
// 'Unique Rows' property required for SQLOLEDB to retrieve things like 'BaseTableName'
dbprops[2] = new tagDBPROP(ODB.DBPROP_UNIQUEROWS, false, keyInfo);
dbprops[2] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_UNIQUEROWS, false, keyInfo);

// otherwise 'Microsoft.Jet.OLEDB.4.0' doesn't support IColumnsRowset
dbprops[3] = new tagDBPROP(ODB.DBPROP_IColumnsRowset, false, true);
dbprops[3] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_IColumnsRowset, false, true);
}
}
propSet.SetPropertySet(0, OleDbPropertySetGuid.Rowset, dbprops);
Expand Down
5 changes: 3 additions & 2 deletions src/libraries/System.Data.OleDb/src/OleDbConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ public new OleDbCommand CreateCommand()
private void DisposeMe(bool disposing)
{
if (disposing)
{ // release mananged objects
{
// release mananged objects
if (DesignMode)
{
// release the object pool in design-mode so that
Expand Down Expand Up @@ -547,7 +548,7 @@ internal void SetDataSourcePropertyValue(Guid propertySet, int propertyID, strin
StringBuilder builder = new StringBuilder();
Debug.Assert(1 == propSet.PropertySetCount, "too many PropertySets");

tagDBPROP[] dbprops = propSet.GetPropertySet(0, out propertySet);
ItagDBPROP[] dbprops = propSet.GetPropertySet(0, out propertySet);
Debug.Assert(1 == dbprops.Length, "too many Properties");

ODB.PropsetSetFailure(builder, description, dbprops[0].dwStatus);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ internal object GetDataSourceValue(Guid propertySet, int propertyID)
internal object GetDataSourcePropertyValue(Guid propertySet, int propertyID)
{
OleDbHResult hr;
tagDBPROP[] dbprops;
ItagDBPROP[] dbprops;
using (IDBPropertiesWrapper idbProperties = IDBProperties())
{
using (PropertyIDSet propidset = new PropertyIDSet(propertySet, propertyID))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,10 +470,10 @@ public override bool TryGetValue(string keyword, out object value)
for (int i = 0; i < count; ++i)
{
Guid propertyset;
tagDBPROP[] props = propset.GetPropertySet(i, out propertyset);
ItagDBPROP[] props = propset.GetPropertySet(i, out propertyset);

// attach the default property value to the property info
foreach (tagDBPROP prop in props)
foreach (ItagDBPROP prop in props)
{
foreach (KeyValuePair<string, OleDbPropertyInfo> entry in hash)
{
Expand Down
74 changes: 40 additions & 34 deletions src/libraries/System.Data.OleDb/src/OleDbDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,8 @@ private void BuildSchemaTableInfoTable(int columnCount, IntPtr columnInfos, bool
for (int i = 0, offset = 0; i < columnCount; ++i, offset += ODB.SizeOf_tagDBCOLUMNINFO)
{
Marshal.PtrToStructure(ADP.IntPtrOffset(columnInfos, offset), dbColumnInfo);
#if WIN32
if (0 >= (int) dbColumnInfo.iOrdinal) {
#else
if (0 >= (long)dbColumnInfo.iOrdinal)
if ((ODB.IsRunningOnX86 && 0 >= (int)dbColumnInfo.iOrdinal) || (!ODB.IsRunningOnX86 && 0 >= (long)dbColumnInfo.iOrdinal))
{
#endif
continue;
}
if (OleDbDataReader.DoColumnDropFilter(dbColumnInfo.dwFlags))
Expand Down Expand Up @@ -536,12 +532,15 @@ private void BuildSchemaTableInfoTable(int columnCount, IntPtr columnInfos, bool
info.columnName = dbColumnInfo.pwszName;
info.type = dbType;
info.ordinal = dbColumnInfo.iOrdinal;
#if WIN32
if (ODB.IsRunningOnX86)
{
info.size = (int)dbColumnInfo.ulColumnSize;
#else
long maxsize = (long)dbColumnInfo.ulColumnSize;
info.size = (((maxsize < 0) || (int.MaxValue < maxsize)) ? int.MaxValue : (int)maxsize);
#endif
}
else
{
long maxsize = (long)dbColumnInfo.ulColumnSize;
info.size = (((maxsize < 0) || (int.MaxValue < maxsize)) ? int.MaxValue : (int)maxsize);
}
info.flags = dbColumnInfo.dwFlags;
info.precision = dbColumnInfo.bPrecision;
info.scale = dbColumnInfo.bScale;
Expand Down Expand Up @@ -1204,21 +1203,30 @@ private void ProcessResults(OleDbHResult hr)

private static IntPtr AddRecordsAffected(IntPtr recordsAffected, IntPtr affected)
{
#if WIN32
if (0 <= (int)affected) {
if (0 <= (int)recordsAffected) {
return (IntPtr)((int)recordsAffected + (int)affected);
#else
if (0 <= (long)affected)
if (ODB.IsRunningOnX86)
{
if (0 <= (long)recordsAffected)
if (0 <= (int)affected)
{
return (IntPtr)((long)recordsAffected + (long)affected);
#endif
if (0 <= (int)recordsAffected)
{
return (IntPtr)((int)recordsAffected + (int)affected);
}
return affected;
}
return recordsAffected;
}
else
{
if (0 <= (long)affected)
{
if (0 <= (long)recordsAffected)
{
return (IntPtr)((long)recordsAffected + (long)affected);
}
return affected;
}
return affected;
return recordsAffected;
}
return recordsAffected;
}

public override int VisibleFieldCount
Expand Down Expand Up @@ -1833,7 +1841,7 @@ private object GetPropertyValue(int propertyId)
private object GetPropertyOnRowset(Guid propertySet, int propertyID)
{
OleDbHResult hr;
tagDBPROP[] dbprops;
ItagDBPROP[] dbprops;
UnsafeNativeMethods.IRowsetInfo irowsetinfo = IRowsetInfo();

using (PropertyIDSet propidset = new PropertyIDSet(propertySet, propertyID))
Expand Down Expand Up @@ -2494,12 +2502,8 @@ internal void DumpToSchemaTable(UnsafeNativeMethods.IRowset rowset)
info.isHidden = true;
visibleCount--;
}
#if WIN32
else if (0 >= (int)info.ordinal) {
#else
else if (0 >= (long)info.ordinal)
else if ((ODB.IsRunningOnX86 && 0 >= (int)info.ordinal) || (!ODB.IsRunningOnX86 && 0 >= (long)info.ordinal))
{
#endif
#if DEBUG
if (AdapterSwitches.DataSchema.TraceVerbose)
{
Expand Down Expand Up @@ -2612,13 +2616,15 @@ int IComparable.CompareTo(object obj)
{
if (isHidden == (obj as MetaData).isHidden)
{
#if WIN32
return ((int)ordinal - (int)(obj as MetaData).ordinal);
#else
long v = ((long)ordinal - (long)(obj as MetaData).ordinal);
return ((0 < v) ? 1 : ((v < 0) ? -1 : 0));
#endif

if (ODB.IsRunningOnX86)
{
return ((int)ordinal - (int)(obj as MetaData).ordinal);
}
else
{
long v = ((long)ordinal - (long)(obj as MetaData).ordinal);
return ((0 < v) ? 1 : ((v < 0) ? -1 : 0));
}
}
return (isHidden) ? 1 : -1; // ensure that all hidden columns come after non-hidden columns
}
Expand Down
114 changes: 104 additions & 10 deletions src/libraries/System.Data.OleDb/src/OleDbStruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,52 @@ internal tagDBPROPSET(int propertyCount, Guid propertySet)
VARIANT vValue;
}
#endif
#if (WIN32 && !ARCH_arm)
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 2)]
#else

internal interface ItagDBPROP
{
OleDbPropertyStatus dwStatus { get; }
object vValue { get; }
int dwPropertyID { get; }
}

[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal sealed class tagDBPROP_x86 : ItagDBPROP
{
OleDbPropertyStatus ItagDBPROP.dwStatus => this.dwStatus;

object ItagDBPROP.vValue => this.vValue;

int ItagDBPROP.dwPropertyID => this.dwPropertyID;

internal int dwPropertyID;
internal int dwOptions;
internal OleDbPropertyStatus dwStatus;

internal tagDBIDX columnid;

// Variant
[MarshalAs(UnmanagedType.Struct)] internal object vValue;

internal tagDBPROP_x86()
{
}

internal tagDBPROP_x86(int propertyID, bool required, object value)
{
dwPropertyID = propertyID;
dwOptions = ((required) ? ODB.DBPROPOPTIONS_REQUIRED : ODB.DBPROPOPTIONS_OPTIONAL);
vValue = value;
}
}

[StructLayout(LayoutKind.Sequential, Pack = 8)]
#endif
internal sealed class tagDBPROP
internal sealed class tagDBPROP : ItagDBPROP
{
OleDbPropertyStatus ItagDBPROP.dwStatus => this.dwStatus;

object ItagDBPROP.vValue => this.vValue;

int ItagDBPROP.dwPropertyID => this.dwPropertyID;
internal int dwPropertyID;
internal int dwOptions;
internal OleDbPropertyStatus dwStatus;
Expand Down Expand Up @@ -449,13 +488,55 @@ internal tagDBPROPINFOSET()
VARIANT vValues;
}
#endif
#if (WIN32 && !ARCH_arm)
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 2)]
#else

internal interface ItagDBPROPINFO
{
int dwPropertyID { get; }
int dwFlags { get; }
int vtType { get; }
object vValue { get; }
string pwszDescription { get; }
}

[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal sealed class tagDBPROPINFO_x86 : ItagDBPROPINFO
{
int ItagDBPROPINFO.dwPropertyID => this.dwPropertyID;

int ItagDBPROPINFO.dwFlags => this.dwFlags;

int ItagDBPROPINFO.vtType => this.vtType;

object ItagDBPROPINFO.vValue => this.vValue;

string ItagDBPROPINFO.pwszDescription => this.pwszDescription;

[MarshalAs(UnmanagedType.LPWStr)] internal string pwszDescription;

internal int dwPropertyID;
internal int dwFlags;

internal short vtType;

[MarshalAs(UnmanagedType.Struct)] internal object vValue;

internal tagDBPROPINFO_x86()
{
}
}

[StructLayout(LayoutKind.Sequential, Pack = 8)]
#endif
internal sealed class tagDBPROPINFO
internal sealed class tagDBPROPINFO : ItagDBPROPINFO
{
int ItagDBPROPINFO.dwPropertyID => this.dwPropertyID;

int ItagDBPROPINFO.dwFlags => this.dwFlags;

int ItagDBPROPINFO.vtType => this.vtType;

object ItagDBPROPINFO.vValue => this.vValue;

string ItagDBPROPINFO.pwszDescription => this.pwszDescription;
[MarshalAs(UnmanagedType.LPWStr)] internal string pwszDescription;

internal int dwPropertyID;
Expand Down Expand Up @@ -488,4 +569,17 @@ internal struct tagDBPROPIDSET
internal int cPropertyIDs;
internal Guid guidPropertySet;
}

internal static class OleDbStructHelpers
{
internal static ItagDBPROPINFO CreateTagDbPropInfo() =>
ODB.IsRunningOnX86 ? (ItagDBPROPINFO)new tagDBPROPINFO_x86() : new tagDBPROPINFO();

internal static ItagDBPROP CreateTagDbProp(int propertyID, bool required, object value) =>
ODB.IsRunningOnX86 ? (ItagDBPROP) new tagDBPROP_x86(propertyID, required, value) :
new tagDBPROP(propertyID, required, value);

internal static ItagDBPROP CreateTagDbProp() =>
ODB.IsRunningOnX86 ? (ItagDBPROP) new tagDBPROP_x86() : new tagDBPROP();
}
}
Loading