in EsentInterop/JetApi.cs [4813:4928]
public int JetEnumerateColumns(
JET_SESID sesid,
JET_TABLEID tableid,
EnumerateColumnsGrbit grbit,
out IEnumerable<EnumeratedColumn> enumeratedColumns)
{
unsafe
{
// NOTE: We must never throw an exception up through ESE or it will corrupt its internal state!
Exception allocatorException = null;
JET_PFNREALLOC allocator = (c, pv, cb) =>
{
try
{
if (pv == IntPtr.Zero)
{
// NOTE: this will allocate memory if cb == 0 and that is what we want.
return Marshal.AllocHGlobal(new IntPtr(cb));
}
if (cb == 0)
{
Marshal.FreeHGlobal(pv);
return IntPtr.Zero;
}
return Marshal.ReAllocHGlobal(pv, new IntPtr(cb));
}
catch (OutOfMemoryException)
{
return IntPtr.Zero;
}
#if !MANAGEDESENT_ON_WSA // Thread model has changed in windows store apps.
catch (ThreadAbortException e)
{
LibraryHelpers.ThreadResetAbort();
allocatorException = e;
return IntPtr.Zero;
}
#endif
catch (Exception e)
{
allocatorException = e;
return IntPtr.Zero;
}
};
uint nativeEnumColumnCount;
NATIVE_ENUMCOLUMN* nativeEnumColumns;
int err = Implementation.NativeMethods.JetEnumerateColumns(
sesid.Value,
tableid.Value,
0,
null,
out nativeEnumColumnCount,
out nativeEnumColumns,
allocator,
IntPtr.Zero,
int.MaxValue,
(uint)(grbit & ~EnumerateColumnsGrbit.EnumerateCompressOutput));
var columns = new EnumeratedColumn[nativeEnumColumnCount];
for (int i = 0; i < nativeEnumColumnCount; ++i)
{
columns[i] = new EnumeratedColumn();
columns[i].Id = new JET_COLUMNID { Value = nativeEnumColumns[i].columnid };
columns[i].Error = nativeEnumColumns[i].err < 0 ? (JET_err)nativeEnumColumns[i].err : JET_err.Success;
columns[i].Warning = nativeEnumColumns[i].err > 0 ? (JET_wrn)nativeEnumColumns[i].err : JET_wrn.Success;
if ((JET_wrn)nativeEnumColumns[i].err == JET_wrn.Success)
{
EnumeratedColumn.Value[] values = new EnumeratedColumn.Value[nativeEnumColumns[i].cEnumColumnValue];
columns[i].Values = values;
for (int j = 0; j < nativeEnumColumns[i].cEnumColumnValue; j++)
{
values[j] = new EnumeratedColumn.Value();
values[j].Ordinal = j + 1;
values[j].Warning = (JET_wrn)nativeEnumColumns[i].rgEnumColumnValue[j].err;
values[j].Bytes = new byte[(int)nativeEnumColumns[i].rgEnumColumnValue[j].cbData];
Marshal.Copy(
nativeEnumColumns[i].rgEnumColumnValue[j].pvData,
values[j].Bytes,
0,
(int)nativeEnumColumns[i].rgEnumColumnValue[j].cbData);
if (nativeEnumColumns[i].rgEnumColumnValue[j].pvData != IntPtr.Zero)
{
allocator(IntPtr.Zero, nativeEnumColumns[i].rgEnumColumnValue[j].pvData, 0);
}
}
if (nativeEnumColumns[i].rgEnumColumnValue != null)
{
allocator(IntPtr.Zero, new IntPtr(nativeEnumColumns[i].rgEnumColumnValue), 0);
}
}
}
if (nativeEnumColumns != null)
{
allocator(IntPtr.Zero, new IntPtr(nativeEnumColumns), 0);
}
if (allocatorException != null)
{
#if !MANAGEDESENT_ON_WSA // Thread model has changed in Windows store apps.
if (allocatorException is ThreadAbortException)
{
Thread.CurrentThread.Abort();
}
#endif
throw allocatorException;
}
enumeratedColumns = columns;
return Err(err);
}
}