public int JetEnumerateColumns()

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);
            }
        }