Compare commits

...

8 Commits

16 changed files with 12274 additions and 61 deletions

View File

@ -0,0 +1,13 @@
#if !(NET6_0_OR_GREATER)
namespace System.Diagnostics;
/// <summary>
/// Types and Methods attributed with StackTraceHidden will be omitted from the stack trace text shown in StackTrace.ToString() and Exception.StackTrace
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
public sealed class StackTraceHiddenAttribute : Attribute
{
/// <summary>Initializes a new instance of the <see cref="StackTraceHiddenAttribute"/> class.</summary>
public StackTraceHiddenAttribute() { }
}
#endif

View File

@ -1,4 +1,8 @@
using System.Runtime.InteropServices.ComTypes;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using static Vanara.PInvoke.Rpc;
using STATSTG = System.Runtime.InteropServices.ComTypes.STATSTG;
@ -4076,4 +4080,116 @@ public static partial class Ole32
/// </summary>
public HRESULT hr;
}
/// <summary>Unmanaged memory methods for IMalloc.</summary>
/// <seealso cref="IMemoryMethods"/>
public sealed class IMallocMemoryMethods : MemoryMethodsBase
{
[ThreadStatic]
internal static Lazy<IMalloc> malloc = new(() => GetMalloc());
/// <summary>Gets a static instance of this class.</summary>
/// <value>The instance.</value>
public static IMemoryMethods Instance { get; } = new IMallocMemoryMethods();
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
/// <param name="size">The size, in bytes, of memory to allocate.</param>
/// <returns>A memory handle.</returns>
public override IntPtr AllocMem(int size) => (malloc?.Value ?? GetMalloc()).Alloc(size);
/// <summary>Frees the memory associated with a handle.</summary>
/// <param name="hMem">A memory handle.</param>
public override void FreeMem(IntPtr hMem) => (malloc?.Value ?? GetMalloc()).Free(hMem);
/// <summary>Retrieves the size of a previously allocated block of memory.</summary>
/// <param name="hMem">A pointer to the block of memory.</param>
/// <returns>The size of the allocated memory block in bytes or, if <paramref name="hMem"/> is a NULL pointer, -1.</returns>
public SizeT GetSize(IntPtr hMem) => (malloc?.Value ?? GetMalloc()).GetSize(hMem);
/// <summary>Gets the reallocation method.</summary>
/// <param name="hMem">A memory handle.</param>
/// <param name="size">The size, in bytes, of memory to allocate.</param>
/// <returns>A memory handle.</returns>
public override IntPtr ReAllocMem(IntPtr hMem, int size) => (malloc?.Value ?? GetMalloc()).Realloc(hMem, size);
private static IMalloc GetMalloc(uint dwMemContext = 1) { CoGetMalloc(dwMemContext, out var m).ThrowIfFailed(); return m; }
}
/// <summary>Safe handle to IMalloc memory.</summary>
public class SafeIMallocHandle : SafeMemoryHandleExt<IMallocMemoryMethods>
{
/// <summary>Initializes a new instance of the <see cref="SafeMemoryHandle{T}"/> class.</summary>
/// <param name="size">The size of memory to allocate, in bytes.</param>
/// <exception cref="ArgumentOutOfRangeException">size - The value of this argument must be non-negative</exception>
public SafeIMallocHandle(SizeT size = default) : base(size) { }
/// <summary>Initializes a new instance of the <see cref="SafeMemoryHandle{T}"/> class.</summary>
/// <param name="handle">The handle.</param>
/// <param name="size">The size of memory allocated to the handle, in bytes.</param>
/// <param name="ownsHandle">if set to <c>true</c> if this class is responsible for freeing the memory on disposal.</param>
public SafeIMallocHandle(IntPtr handle, SizeT size = default, bool ownsHandle = true) : base(handle, size <= 0 ? mm.GetSize(handle) : size, ownsHandle) { }
/// <summary>
/// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native
/// array equivalent.
/// </summary>
/// <param name="bytes">Array of unmanaged pointers</param>
/// <returns>SafeHGlobalHandle object to an native (unmanaged) array of pointers</returns>
public SafeIMallocHandle(byte[] bytes) : base(bytes) { }
/// <summary>Allocates from unmanaged memory to represent a Unicode string (WSTR) and marshal this to a native PWSTR.</summary>
/// <param name="s">The string value.</param>
/// <param name="charSet">The character set of the string.</param>
/// <returns>SafeMemoryHandleExt object to an native (unmanaged) string</returns>
public SafeIMallocHandle(string s, CharSet charSet = CharSet.Unicode) : base(s, charSet) { }
/// <summary>Initializes a new instance of the <see cref="SafeIMallocHandle"/> class.</summary>
[ExcludeFromCodeCoverage]
internal SafeIMallocHandle() : base(0) { }
/// <summary>Represents a NULL memory pointer.</summary>
public static SafeIMallocHandle Null => new(IntPtr.Zero, 0, false);
/// <inheritdoc/>
public override SizeT Size { get => sz = mm.GetSize(handle); set => base.Size = value; }
/// <summary>
/// Allocates from unmanaged memory to represent a structure with a variable length array at the end and marshal these structure
/// elements. It is the callers responsibility to marshal what precedes the trailing array into the unmanaged memory. ONLY
/// structures with attribute StructLayout of LayoutKind.Sequential are supported.
/// </summary>
/// <typeparam name="T">Type of the trailing array of structures</typeparam>
/// <param name="values">Collection of structure objects</param>
/// <param name="count">
/// Number of items in <paramref name="values"/>. Setting this value to -1 will cause the method to get the count by iterating
/// through <paramref name="values"/>.
/// </param>
/// <param name="prefixBytes">Number of bytes preceding the trailing array of structures</param>
/// <returns><see cref="SafeIMallocHandle"/> object to an native (unmanaged) structure with a trail array of structures</returns>
public static SafeIMallocHandle CreateFromList<T>(IEnumerable<T> values, int count = -1, int prefixBytes = 0) =>
new(InteropExtensions.MarshalToPtr(count < 0 ? values : values.Take(count), mm.AllocMem, out int s, prefixBytes), s);
/// <summary>Allocates from unmanaged memory sufficient memory to hold an array of strings.</summary>
/// <param name="values">The list of strings.</param>
/// <param name="packing">The packing type for the strings.</param>
/// <param name="charSet">The character set to use for the strings.</param>
/// <param name="prefixBytes">Number of bytes preceding the trailing strings.</param>
/// <returns>
/// <see cref="SafeIMallocHandle"/> object to an native (unmanaged) array of strings stored using the <paramref name="packing"/>
/// model and the character set defined by <paramref name="charSet"/>.
/// </returns>
public static SafeIMallocHandle CreateFromStringList(IEnumerable<string> values, StringListPackMethod packing = StringListPackMethod.Concatenated,
CharSet charSet = CharSet.Auto, int prefixBytes = 0) => new(InteropExtensions.MarshalToPtr(values, packing, mm.AllocMem, out int s, charSet, prefixBytes), s);
/// <summary>Allocates from unmanaged memory sufficient memory to hold an object of type T.</summary>
/// <typeparam name="T">Native type</typeparam>
/// <param name="value">The value.</param>
/// <returns><see cref="SafeIMallocHandle"/> object to an native (unmanaged) memory block the size of T.</returns>
public static SafeIMallocHandle CreateFromStructure<T>(in T? value = default) => new(InteropExtensions.MarshalToPtr(value, mm.AllocMem, out int s), s);
/// <summary>Converts an <see cref="IntPtr"/> to a <see cref="SafeIMallocHandle"/> where it owns the reference.</summary>
/// <param name="ptr">The <see cref="IntPtr"/>.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SafeIMallocHandle(IntPtr ptr) => new(ptr, 0, true);
}
}

View File

@ -2,6 +2,9 @@
public static partial class Ole32
{
/// <summary>IID_IUnknown</summary>
public static readonly Guid IID_IUnknown = new("00000000-0000-0000-C000-000000000046");
/// <summary>Enables a class of objects to be created.</summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/unknwnbase/nn-unknwnbase-iclassfactory
[PInvokeData("unknwnbase.h", MSDNShortId = "f624f833-2b69-43bc-92cd-c4ecbe6051c5")]

4623
PInvoke/OleDb/DbS.cs Normal file

File diff suppressed because it is too large Load Diff

206
PInvoke/OleDb/NTQuery.cs Normal file
View File

@ -0,0 +1,206 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
namespace Vanara.PInvoke;
public static partial class OleDb
{
public const int CI_VERSION_WDS30 = 0x102; // 258
public const int CI_VERSION_WDS40 = 0x109; // 265
public const int CI_VERSION_WIN70 = 0x700; // 1792
//
// Use this path for the null catalog, one that doesn't have an index.
// Use it to search for properties of files that are not indexed.
//
public const string CINULLCATALOG = "::_noindex_::";
//
// Use this path to connect to the server for administration work
// (i.e. DocStoreAdmin.) No catalog is associated with the connection
//
public const string CIADMIN = "::_nodocstore_::";
// The Index Server Data Source Object Guid
public static readonly Guid CLSID_INDEX_SERVER_DSO = new(0xF9AE8980, 0x7E52, 0x11d0, 0x89, 0x64, 0x00, 0xC0, 0x4F, 0xD6, 0x11, 0xD7);
// The filename PKEY_Filename property set
public static readonly Guid PSGUID_FILENAME = new(0x41CF5AE0, 0xF75A, 0x4806, 0xBD, 0x87, 0x59, 0xC7, 0xD9, 0x24, 0x8E, 0xB9);
public const int PID_FILENAME = 100;
// File System Content Index Framework property set
public static readonly Guid DBPROPSET_FSCIFRMWRK_EXT = new(0xA9BD1526, 0x6A80, 0x11D0, 0x8C, 0x9D, 0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E);
public const int DBPROP_CI_CATALOG_NAME = 2;
public const int DBPROP_CI_INCLUDE_SCOPES = 3;
public const int DBPROP_CI_DEPTHS = 4; // obsolete
public const int DBPROP_CI_SCOPE_FLAGS = 4;
public const int DBPROP_CI_EXCLUDE_SCOPES = 5;
public const int DBPROP_CI_SECURITY_ID = 6;
public const int DBPROP_CI_QUERY_TYPE = 7;
public const int DBPROP_CI_PROVIDER = 8;
// The VT_UI4 value of DBPROP_CI_PROVIDER
public const uint CI_PROVIDER_MSSEARCH = 1; // Only try MSSearch
public const uint CI_PROVIDER_INDEXING_SERVICE = 2; // Only try Indexing Service
public const uint CI_PROVIDER_ALL = 0xffffffff; // Try all -- the default
// Session level Query Extension property set
public static readonly Guid DBPROPSET_SESS_QUERYEXT = new(0x63623309, 0x2d8b, 0x4d17, 0xb1, 0x52, 0x6e, 0x29, 0x56, 0xc2, 0x6a, 0x70);
public const int DBPROP_DEFAULT_EQUALS_BEHAVIOR = 2;
// Query Extension property set
public static readonly Guid DBPROPSET_QUERYEXT = new(0xA7AC77ED, 0xF8D7, 0x11CE, 0xA7, 0x98, 0x00, 0x20, 0xF8, 0x00, 0x80, 0x25);
public const int DBPROP_USECONTENTINDEX = 2;
public const int DBPROP_DEFERNONINDEXEDTRIMMING = 3;
public const int DBPROP_USEEXTENDEDDBTYPES = 4;
public const int DBPROP_IGNORENOISEONLYCLAUSES = 5;
public const int DBPROP_GENERICOPTIONS_STRING = 6;
public const int DBPROP_FIRSTROWS = 7;
public const int DBPROP_DEFERCATALOGVERIFICATION = 8;
public const int DBPROP_CATALOGLISTID = 9;
public const int DBPROP_GENERATEPARSETREE = 10;
public const int DBPROP_APPLICATION_NAME = 11;
public const int DBPROP_FREETEXTANYTERM = 12;
public const int DBPROP_FREETEXTUSESTEMMING = 13;
public const int DBPROP_IGNORESBRI = 14;
public const int DBPROP_DONOTCOMPUTEEXPENSIVEPROPS = 15;
public const int DBPROP_ENABLEROWSETEVENTS = 16;
// Content Index Framework Core property set
public static readonly Guid DBPROPSET_CIFRMWRKCORE_EXT = new(0xafafaca5, 0xb5d1, 0x11d0, 0x8c, 0x62, 0x00, 0xc0, 0x4f, 0xc2, 0xdb, 0x8d);
public const int DBPROP_MACHINE = 2;
public const int DBPROP_CLIENT_CLSID = 3;
// MSIDXS Rowset property set
public static readonly Guid DBPROPSET_MSIDXS_ROWSETEXT = new(0xaa6ee6b0, 0xe828, 0x11d0, 0xb2, 0x3e, 0x00, 0xaa, 0x00, 0x47, 0xfc, 0x01);
public const int MSIDXSPROP_ROWSETQUERYSTATUS = 2;
public const int MSIDXSPROP_COMMAND_LOCALE_STRING = 3;
public const int MSIDXSPROP_QUERY_RESTRICTION = 4;
public const int MSIDXSPROP_PARSE_TREE = 5;
public const int MSIDXSPROP_MAX_RANK = 6;
public const int MSIDXSPROP_RESULTS_FOUND = 7;
public const int MSIDXSPROP_WHEREID = 8;
public const int MSIDXSPROP_SERVER_VERSION = 9;
public const int MSIDXSPROP_SERVER_WINVER_MAJOR = 10;
public const int MSIDXSPROP_SERVER_WINVER_MINOR = 11;
public const int MSIDXSPROP_SERVER_NLSVERSION = 12;
public const int MSIDXSPROP_SERVER_NLSVER_DEFINED = 13;
public const int MSIDXSPROP_SAME_SORTORDER_USED = 14;
//
// Query status values returned by MSIDXSPROP_ROWSETQUERYSTATUS
//
// Bits Effect
// ----- -----------------------------------------------------
// 00-02 Fill Status: How data is being updated, if at all.
// 03-15 Bitfield query reliability: How accurate the result is
public const uint STAT_BUSY = 0;
public const uint STAT_ERROR = 0x1;
public const uint STAT_DONE = 0x2;
public const uint STAT_REFRESH = 0x3;
public const uint STAT_PARTIAL_SCOPE = 0x8;
public const uint STAT_NOISE_WORDS = 0x10;
public const uint STAT_CONTENT_OUT_OF_DATE = 0x20;
public const uint STAT_REFRESH_INCOMPLETE = 0x40;
public const uint STAT_CONTENT_QUERY_INCOMPLETE = 0x80;
public const uint STAT_TIME_LIMIT_EXCEEDED = 0x100;
public const uint STAT_SHARING_VIOLATION = 0x200;
public const uint STAT_MISSING_RELDOC = 0x400;
public const uint STAT_MISSING_PROP_IN_RELDOC = 0x800;
public const uint STAT_RELDOC_ACCESS_DENIED = 0x1000;
public const uint STAT_COALESCE_COMP_ALL_NOISE = 0x2000;
public static uint QUERY_FILL_STATUS(uint x) => x & 0x7;
public static uint QUERY_RELIABILITY_STATUS(uint x) => x & 0xFFF8;
// Scope flags
public const int QUERY_SHALLOW = 0;
public const int QUERY_DEEP = 1;
public const int QUERY_PHYSICAL_PATH = 0;
public const int QUERY_VIRTUAL_PATH = 2;
// query property set (PSGUID_QUERY) properties not defined in oledb.h
public const int PROPID_QUERY_WORKID = 5;
public const int PROPID_QUERY_UNFILTERED = 7;
public const int PROPID_QUERY_VIRTUALPATH = 9;
public const int PROPID_QUERY_LASTSEENTIME = 10;
//
// Change or get the current state of a catalog specified.
//
public const int CICAT_STOPPED = 0x1;
public const int CICAT_READONLY = 0x2;
public const int CICAT_WRITABLE = 0x4;
public const int CICAT_NO_QUERY = 0x8;
public const int CICAT_GET_STATE = 0x10;
public const int CICAT_ALL_OPENED = 0x20;
//
// Query catalog state
//
public const int CI_STATE_SHADOW_MERGE = 0x0001; // Index is performing a shadow merge
public const int CI_STATE_MASTER_MERGE = 0x0002; // Index is performing a master merge
public const int CI_STATE_CONTENT_SCAN_REQUIRED = 0x0004; // Index is likely corrupt, and a rescan is required
public const int CI_STATE_ANNEALING_MERGE = 0x0008; // Index is performing an annealing (optimizing) merge
public const int CI_STATE_SCANNING = 0x0010; // Scans are in-progress
public const int CI_STATE_RECOVERING = 0x0020; // Index metadata is being recovered
public const int CI_STATE_INDEX_MIGRATION_MERGE = 0x0040; // Reserved for future use
public const int CI_STATE_LOW_MEMORY = 0x0080; // Indexing is paused due to low memory availability
public const int CI_STATE_HIGH_IO = 0x0100; // Indexing is paused due to a high rate of I/O
public const int CI_STATE_MASTER_MERGE_PAUSED = 0x0200; // Master merge is paused
public const int CI_STATE_READ_ONLY = 0x0400; // Indexing has been manually paused (read-only)
public const int CI_STATE_BATTERY_POWER = 0x0800; // Indexing is paused to conserve battery life
public const int CI_STATE_USER_ACTIVE = 0x1000; // Indexing is paused due to high user activity (keyboard/mouse)
public const int CI_STATE_STARTING = 0x2000; // Index is still starting up
public const int CI_STATE_READING_USNS = 0x4000; // USNs on NTFS volumes are being processed
public const int CI_STATE_DELETION_MERGE = 0x8000; // Index is performing a deletion merge
public const int CI_STATE_LOW_DISK = 0x10000; // Index is paused due to low disk availability
public const int CI_STATE_HIGH_CPU = 0x20000; // Index is paused due to high CPU
public const int CI_STATE_BATTERY_POLICY = 0x40000; // Indexing is paused due to backoff on battery policy
[StructLayout(LayoutKind.Sequential)]
public struct CI_STATE
{
public uint cbStruct;
public uint cWordList;
public uint cPersistentIndex;
public uint cQueries;
public uint cDocuments;
public uint cFreshTest;
public uint dwMergeProgress;
public uint eState;
public uint cFilteredDocuments;
public uint cTotalDocuments;
public uint cPendingScans;
public uint dwIndexSize;
public uint cUniqueKeys;
public uint cSecQDocuments;
public uint dwPropCacheSize;
}
[StructLayout(LayoutKind.Sequential)]
public struct CIPROPERTYDEF
{
public string wcsFriendlyName;
public uint dbType;
public DBID dbCol;
}
}

617
PInvoke/OleDb/OleDBErr.cs Normal file
View File

@ -0,0 +1,617 @@
using static Vanara.PInvoke.OleAut32;
namespace Vanara.PInvoke;
public static partial class OleDb
{
static OleDb()
{
StaticFieldValueHash.AddFields<HRESULT, int, OleDbErr>(Lib_OleDb);
ErrorHelper.AddErrorMessageLookupFunction<OleDbErr>(GetOleDbErrMsg);
}
private static string GetOleDbErrMsg(uint val, string? lib)
{
try
{
// Obtain the current Error object, if any, by using the OLE Automation GetErrorInfo function, which will give us back an
// IErrorInfo interface pointer if successful
GetErrorInfo(0, out var pIErrorInfo).ThrowIfFailed();
// We've got the IErrorInfo interface pointer on the Error object
if (pIErrorInfo is not null)
{
// OLE DB extends the OLE Automation error model by allowing Error objects to support the IErrorRecords interface; this
// interface can expose information on multiple errors.
//IErrorRecords? pIErrorRecords = pIErrorInfo as IErrorRecords;
//if (pIErrorRecords is not null)
//{
// StringBuilder sb = new(1024);
// // Loop through the set of error records and display the error information for each one
// for (uint iRecord = 0; iRecord < pIErrorRecords.GetRecordCount(); iRecord++)
// {
// pIErrorInfo = pIErrorRecords.GetErrorInfo(iRecord, LCID.LOCALE_USER_DEFAULT);
// pIErrorInfo.GetDescription(out var bstrDescription).ThrowIfFailed();
// sb.AppendLine(bstrDescription);
// }
// return sb.ToString();
//}
// The object didn't support IErrorRecords; display the error information for this single error
//else
//{
// Get the description of the error
pIErrorInfo.GetDescription(out var bstrDescription).ThrowIfFailed();
return bstrDescription;
//}
}
}
catch
{
}
return "";
}
private static void myDisplayErrorRecord(HRESULT hrReturned, uint iRecord, IErrorRecords pIErrorRecords)
{
}
private static void myGetSqlErrorInfo(uint iRecord, IErrorRecords pIErrorRecords, out string? pBstr, out int plNativeError)
{
// Attempt to get the ISQLErrorInfo interface for this error record through GetCustomErrorObject. Note that ISQLErrorInfo is not
// mandatory, so failure is acceptable here
pIErrorRecords.GetCustomErrorObject(iRecord, //iRecord
typeof(ISQLErrorInfo).GUID, //riid
out var pISQLErrorInfo); //ppISQLErrorInfo
// If we obtained the ISQLErrorInfo interface, get the SQL error string and native error code for this error
if (pISQLErrorInfo is not null)
((ISQLErrorInfo)pISQLErrorInfo).GetSQLInfo(out pBstr, out plNativeError);
else { pBstr = null; plNativeError = 0; }
}
/// <summary>HRESULT values for OLE DB errors. These values are returned by OLE DB methods.</summary>
[PInvokeData("oledberr.h")]
public enum OleDbErr
{
/// <summary>Accessor is invalid.</summary>
DB_E_BADACCESSORHANDLE = unchecked((int)0x80040E00),
/// <summary>Row could not be inserted into the rowset without exceeding provider's maximum number of active rows.</summary>
DB_E_ROWLIMITEXCEEDED = unchecked((int)0x80040E01),
/// <summary>Accessor is read-only. Operation failed.</summary>
DB_E_READONLYACCESSOR = unchecked((int)0x80040E02),
/// <summary>Values violate the database schema.</summary>
DB_E_SCHEMAVIOLATION = unchecked((int)0x80040E03),
/// <summary>Row handle is invalid.</summary>
DB_E_BADROWHANDLE = unchecked((int)0x80040E04),
/// <summary>Object was open.</summary>
DB_E_OBJECTOPEN = unchecked((int)0x80040E05),
/// <summary>Chapter is invalid.</summary>
DB_E_BADCHAPTER = unchecked((int)0x80040E06),
/// <summary>
/// Data or literal value could not be converted to the type of the column in the data source, and the provider was unable to
/// determine which columns could not be converted. Data overflow or sign mismatch was not the cause.
/// </summary>
DB_E_CANTCONVERTVALUE = unchecked((int)0x80040E07),
/// <summary>Binding information is invalid.</summary>
DB_E_BADBINDINFO = unchecked((int)0x80040E08),
/// <summary>Permission denied.</summary>
DB_SEC_E_PERMISSIONDENIED = unchecked((int)0x80040E09),
/// <summary>Column does not contain bookmarks or chapters.</summary>
DB_E_NOTAREFERENCECOLUMN = unchecked((int)0x80040E0A),
/// <summary>Cost limits were rejected.</summary>
DB_E_LIMITREJECTED = unchecked((int)0x80040E0B),
/// <summary>Command text was not set for the command object.</summary>
DB_E_NOCOMMAND = unchecked((int)0x80040E0C),
/// <summary>Query plan within the cost limit cannot be found.</summary>
DB_E_COSTLIMIT = unchecked((int)0x80040E0D),
/// <summary>Bookmark is invalid.</summary>
DB_E_BADBOOKMARK = unchecked((int)0x80040E0E),
/// <summary>Lock mode is invalid.</summary>
DB_E_BADLOCKMODE = unchecked((int)0x80040E0F),
/// <summary>No value given for one or more required parameters.</summary>
DB_E_PARAMNOTOPTIONAL = unchecked((int)0x80040E10),
/// <summary>Column ID is invalid.</summary>
DB_E_BADCOLUMNID = unchecked((int)0x80040E11),
/// <summary>Numerator was greater than denominator. Values must express ratio between zero and 1.</summary>
DB_E_BADRATIO = unchecked((int)0x80040E12),
/// <summary>Value is invalid.</summary>
DB_E_BADVALUES = unchecked((int)0x80040E13),
/// <summary>One or more errors occurred during processing of command.</summary>
DB_E_ERRORSINCOMMAND = unchecked((int)0x80040E14),
/// <summary>Command cannot be canceled.</summary>
DB_E_CANTCANCEL = unchecked((int)0x80040E15),
/// <summary>Command dialect is not supported by this provider.</summary>
DB_E_DIALECTNOTSUPPORTED = unchecked((int)0x80040E16),
/// <summary>Data source object could not be created because the named data source already exists.</summary>
DB_E_DUPLICATEDATASOURCE = unchecked((int)0x80040E17),
/// <summary>Rowset position cannot be restarted.</summary>
DB_E_CANNOTRESTART = unchecked((int)0x80040E18),
/// <summary>Object or data matching the name, range, or selection criteria was not found within the scope of this operation.</summary>
DB_E_NOTFOUND = unchecked((int)0x80040E19),
/// <summary>Identity cannot be determined for newly inserted rows.</summary>
DB_E_NEWLYINSERTED = unchecked((int)0x80040E1B),
/// <summary>Provider has ownership of this tree.</summary>
DB_E_CANNOTFREE = unchecked((int)0x80040E1A),
/// <summary>Goal was rejected because no nonzero weights were specified for any goals supported. Current goal was not changed.</summary>
DB_E_GOALREJECTED = unchecked((int)0x80040E1C),
/// <summary>Requested conversion is not supported.</summary>
DB_E_UNSUPPORTEDCONVERSION = unchecked((int)0x80040E1D),
/// <summary>No rows were returned because the offset value moves the position before the beginning or after the end of the rowset.</summary>
DB_E_BADSTARTPOSITION = unchecked((int)0x80040E1E),
/// <summary>Information was requested for a query and the query was not set.</summary>
DB_E_NOQUERY = unchecked((int)0x80040E1F),
/// <summary>Consumer's event handler called a non-reentrant method in the provider.</summary>
DB_E_NOTREENTRANT = unchecked((int)0x80040E20),
/// <summary>Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.</summary>
DB_E_ERRORSOCCURRED = unchecked((int)0x80040E21),
/// <summary>
/// Non-NULL controlling IUnknown was specified, and either the requested interface was not IUnknown, or the provider does not
/// support COM aggregation.
/// </summary>
DB_E_NOAGGREGATION = unchecked((int)0x80040E22),
/// <summary>Row handle referred to a deleted row or a row marked for deletion.</summary>
DB_E_DELETEDROW = unchecked((int)0x80040E23),
/// <summary>Rowset does not support fetching backward.</summary>
DB_E_CANTFETCHBACKWARDS = unchecked((int)0x80040E24),
/// <summary>Row handles must all be released before new ones can be obtained.</summary>
DB_E_ROWSNOTRELEASED = unchecked((int)0x80040E25),
/// <summary>One or more storage flags are not supported.</summary>
DB_E_BADSTORAGEFLAG = unchecked((int)0x80040E26),
/// <summary>Comparison operator is invalid.</summary>
DB_E_BADCOMPAREOP = unchecked((int)0x80040E27),
/// <summary>Status flag was neither DBCOLUMNSTATUS_OK nor DBCOLUMNSTATUS_ISNULL.</summary>
DB_E_BADSTATUSVALUE = unchecked((int)0x80040E28),
/// <summary>Rowset does not support scrolling backward.</summary>
DB_E_CANTSCROLLBACKWARDS = unchecked((int)0x80040E29),
/// <summary>Region handle is invalid.</summary>
DB_E_BADREGIONHANDLE = unchecked((int)0x80040E2A),
/// <summary>Set of rows is not contiguous to, or does not overlap, the rows in the watch region.</summary>
DB_E_NONCONTIGUOUSRANGE = unchecked((int)0x80040E2B),
/// <summary>Transition from ALL* to MOVE* or EXTEND* was specified.</summary>
DB_E_INVALIDTRANSITION = unchecked((int)0x80040E2C),
/// <summary>Region is not a proper subregion of the region identified by the watch region handle.</summary>
DB_E_NOTASUBREGION = unchecked((int)0x80040E2D),
/// <summary>Multiple-statement commands are not supported by this provider.</summary>
DB_E_MULTIPLESTATEMENTS = unchecked((int)0x80040E2E),
/// <summary>Value violated the integrity constraints for a column or table.</summary>
DB_E_INTEGRITYVIOLATION = unchecked((int)0x80040E2F),
/// <summary>Type name is invalid.</summary>
DB_E_BADTYPENAME = unchecked((int)0x80040E30),
/// <summary>Execution stopped because a resource limit was reached. No results were returned.</summary>
DB_E_ABORTLIMITREACHED = unchecked((int)0x80040E31),
/// <summary>Command object whose command tree contains a rowset or rowsets cannot be cloned.</summary>
DB_E_ROWSETINCOMMAND = unchecked((int)0x80040E32),
/// <summary>Current tree cannot be represented as text.</summary>
DB_E_CANTTRANSLATE = unchecked((int)0x80040E33),
/// <summary>Index already exists.</summary>
DB_E_DUPLICATEINDEXID = unchecked((int)0x80040E34),
/// <summary>Index does not exist.</summary>
DB_E_NOINDEX = unchecked((int)0x80040E35),
/// <summary>Index is in use.</summary>
DB_E_INDEXINUSE = unchecked((int)0x80040E36),
/// <summary>Table does not exist.</summary>
DB_E_NOTABLE = unchecked((int)0x80040E37),
/// <summary>Rowset used optimistic concurrency and the value of a column has changed since it was last read.</summary>
DB_E_CONCURRENCYVIOLATION = unchecked((int)0x80040E38),
/// <summary>Errors detected during the copy.</summary>
DB_E_BADCOPY = unchecked((int)0x80040E39),
/// <summary>Precision is invalid.</summary>
DB_E_BADPRECISION = unchecked((int)0x80040E3A),
/// <summary>Scale is invalid.</summary>
DB_E_BADSCALE = unchecked((int)0x80040E3B),
/// <summary>Table ID is invalid.</summary>
DB_E_BADTABLEID = unchecked((int)0x80040E3C),
/// <summary>Type is invalid.</summary>
DB_E_BADTYPE = unchecked((int)0x80040E3D),
/// <summary>Column ID already exists or occurred more than once in the array of columns.</summary>
DB_E_DUPLICATECOLUMNID = unchecked((int)0x80040E3E),
/// <summary>Table already exists.</summary>
DB_E_DUPLICATETABLEID = unchecked((int)0x80040E3F),
/// <summary>Table is in use.</summary>
DB_E_TABLEINUSE = unchecked((int)0x80040E40),
/// <summary>Locale ID is not supported.</summary>
DB_E_NOLOCALE = unchecked((int)0x80040E41),
/// <summary>Record number is invalid.</summary>
DB_E_BADRECORDNUM = unchecked((int)0x80040E42),
/// <summary>Form of bookmark is valid, but no row was found to match it.</summary>
DB_E_BOOKMARKSKIPPED = unchecked((int)0x80040E43),
/// <summary>Property value is invalid.</summary>
DB_E_BADPROPERTYVALUE = unchecked((int)0x80040E44),
/// <summary>Rowset is not chaptered.</summary>
DB_E_INVALID = unchecked((int)0x80040E45),
/// <summary>One or more accessor flags were invalid.</summary>
DB_E_BADACCESSORFLAGS = unchecked((int)0x80040E46),
/// <summary>One or more storage flags are invalid.</summary>
DB_E_BADSTORAGEFLAGS = unchecked((int)0x80040E47),
/// <summary>Reference accessors are not supported by this provider.</summary>
DB_E_BYREFACCESSORNOTSUPPORTED = unchecked((int)0x80040E48),
/// <summary>Null accessors are not supported by this provider.</summary>
DB_E_NULLACCESSORNOTSUPPORTED = unchecked((int)0x80040E49),
/// <summary>Command was not prepared.</summary>
DB_E_NOTPREPARED = unchecked((int)0x80040E4A),
/// <summary>Accessor is not a parameter accessor.</summary>
DB_E_BADACCESSORTYPE = unchecked((int)0x80040E4B),
/// <summary>Accessor is write-only.</summary>
DB_E_WRITEONLYACCESSOR = unchecked((int)0x80040E4C),
/// <summary>Authentication failed.</summary>
DB_SEC_E_AUTH_FAILED = unchecked((int)0x80040E4D),
/// <summary>Operation was canceled.</summary>
DB_E_CANCELED = unchecked((int)0x80040E4E),
/// <summary>Rowset is single-chaptered. The chapter was not released.</summary>
DB_E_CHAPTERNOTRELEASED = unchecked((int)0x80040E4F),
/// <summary>Source handle is invalid.</summary>
DB_E_BADSOURCEHANDLE = unchecked((int)0x80040E50),
/// <summary>Provider cannot derive parameter information and SetParameterInfo has not been called.</summary>
DB_E_PARAMUNAVAILABLE = unchecked((int)0x80040E51),
/// <summary>Data source object is already initialized.</summary>
DB_E_ALREADYINITIALIZED = unchecked((int)0x80040E52),
/// <summary>Method is not supported by this provider.</summary>
DB_E_NOTSUPPORTED = unchecked((int)0x80040E53),
/// <summary>Number of rows with pending changes exceeded the limit.</summary>
DB_E_MAXPENDCHANGESEXCEEDED = unchecked((int)0x80040E54),
/// <summary>Column does not exist.</summary>
DB_E_BADORDINAL = unchecked((int)0x80040E55),
/// <summary>Pending changes exist on a row with a reference count of zero.</summary>
DB_E_PENDINGCHANGES = unchecked((int)0x80040E56),
/// <summary>Literal value in the command exceeded the range of the type of the associated column.</summary>
DB_E_DATAOVERFLOW = unchecked((int)0x80040E57),
/// <summary>HRESULT is invalid.</summary>
DB_E_BADHRESULT = unchecked((int)0x80040E58),
/// <summary>Lookup ID is invalid.</summary>
DB_E_BADLOOKUPID = unchecked((int)0x80040E59),
/// <summary>DynamicError ID is invalid.</summary>
DB_E_BADDYNAMICERRORID = unchecked((int)0x80040E5A),
/// <summary>Most recent data for a newly inserted row could not be retrieved because the insert is pending.</summary>
DB_E_PENDINGINSERT = unchecked((int)0x80040E5B),
/// <summary>Conversion flag is invalid.</summary>
DB_E_BADCONVERTFLAG = unchecked((int)0x80040E5C),
/// <summary>Parameter name is unrecognized.</summary>
DB_E_BADPARAMETERNAME = unchecked((int)0x80040E5D),
/// <summary>Multiple storage objects cannot be open simultaneously.</summary>
DB_E_MULTIPLESTORAGE = unchecked((int)0x80040E5E),
/// <summary>Filter cannot be opened.</summary>
DB_E_CANTFILTER = unchecked((int)0x80040E5F),
/// <summary>Order cannot be opened.</summary>
DB_E_CANTORDER = unchecked((int)0x80040E60),
/// <summary>Tuple is invalid.</summary>
MD_E_BADTUPLE = unchecked((int)0x80040E61),
/// <summary>Coordinate is invalid.</summary>
MD_E_BADCOORDINATE = unchecked((int)0x80040E62),
/// <summary>Axis is invalid.</summary>
MD_E_INVALIDAXIS = unchecked((int)0x80040E63),
/// <summary>One or more cell ordinals is invalid.</summary>
MD_E_INVALIDCELLRANGE = unchecked((int)0x80040E64),
/// <summary>Column ID is invalid.</summary>
DB_E_NOCOLUMN = unchecked((int)0x80040E65),
/// <summary>Command does not have a DBID.</summary>
DB_E_COMMANDNOTPERSISTED = unchecked((int)0x80040E67),
/// <summary>DBID already exists.</summary>
DB_E_DUPLICATEID = unchecked((int)0x80040E68),
/// <summary>
/// Session cannot be created because maximum number of active sessions was already reached. Consumer must release one or more
/// sessions before creating a new session object.
/// </summary>
DB_E_OBJECTCREATIONLIMITREACHED = unchecked((int)0x80040E69),
/// <summary>Index ID is invalid.</summary>
DB_E_BADINDEXID = unchecked((int)0x80040E72),
/// <summary>Format of the initialization string does not conform to the OLE DB specification.</summary>
DB_E_BADINITSTRING = unchecked((int)0x80040E73),
/// <summary>No OLE DB providers of this source type are registered.</summary>
DB_E_NOPROVIDERSREGISTERED = unchecked((int)0x80040E74),
/// <summary>Initialization string specifies a provider that does not match the active provider.</summary>
DB_E_MISMATCHEDPROVIDER = unchecked((int)0x80040E75),
/// <summary>DBID is invalid.</summary>
DB_E_BADCOMMANDID = unchecked((int)0x80040E76),
/// <summary>Trustee is invalid.</summary>
SEC_E_BADTRUSTEEID = unchecked((int)0x80040E6A),
/// <summary>Trustee was not recognized for this data source.</summary>
SEC_E_NOTRUSTEEID = unchecked((int)0x80040E6B),
/// <summary>Trustee does not support memberships or collections.</summary>
SEC_E_NOMEMBERSHIPSUPPORT = unchecked((int)0x80040E6C),
/// <summary>Object is invalid or unknown to the provider.</summary>
SEC_E_INVALIDOBJECT = unchecked((int)0x80040E6D),
/// <summary>Object does not have an owner.</summary>
SEC_E_NOOWNER = unchecked((int)0x80040E6E),
/// <summary>Access entry list is invalid.</summary>
SEC_E_INVALIDACCESSENTRYLIST = unchecked((int)0x80040E6F),
/// <summary>Trustee supplied as owner is invalid or unknown to the provider.</summary>
SEC_E_INVALIDOWNER = unchecked((int)0x80040E70),
/// <summary>Permission in the access entry list is invalid.</summary>
SEC_E_INVALIDACCESSENTRY = unchecked((int)0x80040E71),
/// <summary>ConstraintType is invalid or not supported by the provider.</summary>
DB_E_BADCONSTRAINTTYPE = unchecked((int)0x80040E77),
/// <summary>ConstraintType is not DBCONSTRAINTTYPE_FOREIGNKEY and cForeignKeyColumns is not zero.</summary>
DB_E_BADCONSTRAINTFORM = unchecked((int)0x80040E78),
/// <summary>Specified deferrability flag is invalid or not supported by the provider.</summary>
DB_E_BADDEFERRABILITY = unchecked((int)0x80040E79),
/// <summary>MatchType is invalid or the value is not supported by the provider.</summary>
DB_E_BADMATCHTYPE = unchecked((int)0x80040E80),
/// <summary>Constraint update rule or delete rule is invalid.</summary>
DB_E_BADUPDATEDELETERULE = unchecked((int)0x80040E8A),
/// <summary>Constraint ID is invalid.</summary>
DB_E_BADCONSTRAINTID = unchecked((int)0x80040E8B),
/// <summary>Command persistence flag is invalid.</summary>
DB_E_BADCOMMANDFLAGS = unchecked((int)0x80040E8C),
/// <summary>rguidColumnType points to a GUID that does not match the object type of this column, or this column was not set.</summary>
DB_E_OBJECTMISMATCH = unchecked((int)0x80040E8D),
/// <summary>Source row does not exist.</summary>
DB_E_NOSOURCEOBJECT = unchecked((int)0x80040E91),
/// <summary>OLE DB object represented by this URL is locked by one or more other processes.</summary>
DB_E_RESOURCELOCKED = unchecked((int)0x80040E92),
/// <summary>Client requested an object type that is valid only for a collection.</summary>
DB_E_NOTCOLLECTION = unchecked((int)0x80040E93),
/// <summary>Caller requested write access to a read-only object.</summary>
DB_E_READONLY = unchecked((int)0x80040E94),
/// <summary>Asynchronous binding is not supported by this provider.</summary>
DB_E_ASYNCNOTSUPPORTED = unchecked((int)0x80040E95),
/// <summary>Connection to the server for this URL cannot be established.</summary>
DB_E_CANNOTCONNECT = unchecked((int)0x80040E96),
/// <summary>Timeout occurred when attempting to bind to the object.</summary>
DB_E_TIMEOUT = unchecked((int)0x80040E97),
/// <summary>Object cannot be created at this URL because an object named by this URL already exists.</summary>
DB_E_RESOURCEEXISTS = unchecked((int)0x80040E98),
/// <summary>URL is outside of scope.</summary>
DB_E_RESOURCEOUTOFSCOPE = unchecked((int)0x80040E8E),
/// <summary>Column or constraint could not be dropped because it is referenced by a dependent view or constraint.</summary>
DB_E_DROPRESTRICTED = unchecked((int)0x80040E90),
/// <summary>Constraint already exists.</summary>
DB_E_DUPLICATECONSTRAINTID = unchecked((int)0x80040E99),
/// <summary>Object cannot be created at this URL because the server is out of physical storage.</summary>
DB_E_OUTOFSPACE = unchecked((int)0x80040E9A),
/// <summary>Safety settings on this computer prohibit accessing a data source on another domain.</summary>
DB_SEC_E_SAFEMODE_DENIED = unchecked((int)0x80040E9B),
/// <summary>
/// The specified statistic does not exist in the current data source or did not apply to the specified table or it does not support
/// a histogram.
/// </summary>
DB_E_NOSTATISTIC = unchecked((int)0x80040E9C),
/// <summary>Column or table could not be altered because it is referenced by a constraint.</summary>
DB_E_ALTERRESTRICTED = unchecked((int)0x80040E9D),
/// <summary>Requested object type is not supported by the provider.</summary>
DB_E_RESOURCENOTSUPPORTED = unchecked((int)0x80040E9E),
/// <summary>Constraint does not exist.</summary>
DB_E_NOCONSTRAINT = unchecked((int)0x80040E9F),
/// <summary>
/// Requested column is valid, but could not be retrieved. This could be due to a forward only cursor attempting to go backwards in a row.
/// </summary>
DB_E_COLUMNUNAVAILABLE = unchecked((int)0x80040EA0),
/// <summary>Fetching requested number of rows will exceed total number of active rows supported by the rowset.</summary>
DB_S_ROWLIMITEXCEEDED = unchecked(0x00040EC0),
/// <summary>One or more column types are incompatible. Conversion errors will occur during copying.</summary>
DB_S_COLUMNTYPEMISMATCH = unchecked(0x00040EC1),
/// <summary>Parameter type information was overridden by caller.</summary>
DB_S_TYPEINFOOVERRIDDEN = unchecked(0x00040EC2),
/// <summary>Bookmark was skipped for deleted or nonmember row.</summary>
DB_S_BOOKMARKSKIPPED = unchecked(0x00040EC3),
/// <summary>No more rowsets.</summary>
DB_S_NONEXTROWSET = unchecked(0x00040EC5),
/// <summary>Start or end of rowset or chapter was reached.</summary>
DB_S_ENDOFROWSET = unchecked(0x00040EC6),
/// <summary>Command was reexecuted.</summary>
DB_S_COMMANDREEXECUTED = unchecked(0x00040EC7),
/// <summary>Operation succeeded, but status array or string buffer could not be allocated.</summary>
DB_S_BUFFERFULL = unchecked(0x00040EC8),
/// <summary>No more results.</summary>
DB_S_NORESULT = unchecked(0x00040EC9),
/// <summary>Server cannot release or downgrade a lock until the end of the transaction.</summary>
DB_S_CANTRELEASE = unchecked(0x00040ECA),
/// <summary>Weight is not supported or exceeded the supported limit, and was set to 0 or the supported limit.</summary>
DB_S_GOALCHANGED = unchecked(0x00040ECB),
/// <summary>Consumer does not want to receive further notification calls for this operation.</summary>
DB_S_UNWANTEDOPERATION = unchecked(0x00040ECC),
/// <summary>Input dialect was ignored and command was processed using default dialect.</summary>
DB_S_DIALECTIGNORED = unchecked(0x00040ECD),
/// <summary>Consumer does not want to receive further notification calls for this phase.</summary>
DB_S_UNWANTEDPHASE = unchecked(0x00040ECE),
/// <summary>Consumer does not want to receive further notification calls for this reason.</summary>
DB_S_UNWANTEDREASON = unchecked(0x00040ECF),
/// <summary>Operation is being processed asynchronously.</summary>
DB_S_ASYNCHRONOUS = unchecked(0x00040ED0),
/// <summary>
/// Command was executed to reposition to the start of the rowset. Either the order of the columns changed, or columns were added to
/// or removed from the rowset.
/// </summary>
DB_S_COLUMNSCHANGED = unchecked(0x00040ED1),
/// <summary>Method had some errors, which were returned in the error array.</summary>
DB_S_ERRORSRETURNED = unchecked(0x00040ED2),
/// <summary>Row handle is invalid.</summary>
DB_S_BADROWHANDLE = unchecked(0x00040ED3),
/// <summary>Row handle referred to a deleted row.</summary>
DB_S_DELETEDROW = unchecked(0x00040ED4),
/// <summary>
/// Provider cannot keep track of all the changes. Client must refetch the data associated with the watch region by using another method.
/// </summary>
DB_S_TOOMANYCHANGES = unchecked(0x00040ED5),
/// <summary>
/// Execution stopped because a resource limit was reached. Results obtained so far were returned, but execution cannot resume.
/// </summary>
DB_S_STOPLIMITREACHED = unchecked(0x00040ED6),
/// <summary>Lock was upgraded from the value specified.</summary>
DB_S_LOCKUPGRADED = unchecked(0x00040ED8),
/// <summary>One or more properties were changed as allowed by provider.</summary>
DB_S_PROPERTIESCHANGED = unchecked(0x00040ED9),
/// <summary>Multiple-step operation completed with one or more errors. Check each status value.</summary>
DB_S_ERRORSOCCURRED = unchecked(0x00040EDA),
/// <summary>Parameter is invalid.</summary>
DB_S_PARAMUNAVAILABLE = unchecked(0x00040EDB),
/// <summary>Updating a row caused more than one row to be updated in the data source.</summary>
DB_S_MULTIPLECHANGES = unchecked(0x00040EDC),
/// <summary>Row object was requested on a non-singleton result. First row was returned.</summary>
DB_S_NOTSINGLETON = unchecked(0x00040ED7),
/// <summary>Row has no row-specific columns.</summary>
DB_S_NOROWSPECIFICCOLUMNS = unchecked(0x00040EDD),
}
}

5739
PInvoke/OleDb/OleDb.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<ProjectExtensions>
<SupportedDlls>oledb.dll</SupportedDlls>
</ProjectExtensions>
<PropertyGroup>
<Description>PInvoke API (methods, structures and constants) imported from Windows OLE DB.</Description>
<AssemblyName>Vanara.PInvoke.OleDb</AssemblyName>
<AssemblyTitle>$(AssemblyName)</AssemblyTitle>
<PackageId>$(AssemblyName)</PackageId>
<PackageTags>pinvoke;vanara;net-extensions;interop;OleDb</PackageTags>
<PackageReleaseNotes />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Core\Vanara.Core.csproj" />
<ProjectReference Include="..\Odbc32\Vanara.PInvoke.Odbc32.csproj" />
<ProjectReference Include="..\Ole\Vanara.PInvoke.Ole.csproj" />
<ProjectReference Include="..\Shared\Vanara.PInvoke.Shared.csproj" />
</ItemGroup>
</Project>

817
PInvoke/OleDb/msdasc.cs Normal file
View File

@ -0,0 +1,817 @@
namespace Vanara.PInvoke;
public static partial class OleDb
{
/// <summary/>
public static readonly Guid CLSID_EXTENDEDERRORINFO = new(0xc8b522cf, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
/// <summary/>
public static readonly Guid CLSID_MSDAVTM = new(0x0c733a8e, 0x2a1c, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
/// <summary/>
public static readonly Guid CLSID_OLEDB_CONVERSIONLIBRARY = new(0xc8b522d1, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
/// <summary/>
public static readonly Guid CLSID_OLEDB_ENUMERATOR = new(0xc8b522d0, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
/// <summary/>
public static readonly Guid CLSID_OLEDB_ROWPOSITIONLIBRARY = new(0x2048eee6, 0x7fa2, 0x11d0, 0x9e, 0x6a, 0x00, 0xa0, 0xc9, 0x13, 0x8c, 0x29);
/// <summary/>
public static readonly Guid OLEDB_SVC_DSLPropertyPages = new(0x51740c02, 0x7e8e, 0x11d2, 0xa0, 0x2d, 0x00, 0xc0, 0x4f, 0xa3, 0x73, 0x48);
/// <summary/>
public static readonly Guid IID_ISQLRequestDiagFields = new(0x228972f0, 0xb5ff, 0x11d0, 0x8a, 0x80, 0x0, 0xc0, 0x4f, 0xd6, 0x11, 0xcd);
/// <summary/>
public static readonly Guid IID_ISQLGetDiagField = new(0x228972f1, 0xb5ff, 0x11d0, 0x8a, 0x80, 0x0, 0xc0, 0x4f, 0xd6, 0x11, 0xcd);
/// <summary/>
public static readonly Guid IID_IRowsetChangeExtInfo = new(0x0C733A8F, 0x2A1C, 0x11CE, 0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D);
/// <summary/>
public static readonly Guid CLSID_MSDASQL = new(0xC8B522CB, 0x5CF3, 0x11CE, 0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D);
/// <summary/>
public static readonly Guid CLSID_MSDASQL_ENUMERATOR = new(0xC8B522CD, 0x5CF3, 0x11CE, 0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D);
/// <summary/>
public static readonly Guid DBPROPSET_PROVIDERDATASOURCEINFO = new(0x497c60e0, 0x7123, 0x11cf, 0xb1, 0x71, 0x0, 0xaa, 0x0, 0x57, 0x59, 0x9e);
/// <summary/>
public static readonly Guid DBPROPSET_PROVIDERROWSET = new(0x497c60e1, 0x7123, 0x11cf, 0xb1, 0x71, 0x0, 0xaa, 0x0, 0x57, 0x59, 0x9e);
/// <summary/>
public static readonly Guid DBPROPSET_PROVIDERDBINIT = new(0x497c60e2, 0x7123, 0x11cf, 0xb1, 0x71, 0x0, 0xaa, 0x0, 0x57, 0x59, 0x9e);
/// <summary/>
public static readonly Guid DBPROPSET_PROVIDERSTMTATTR = new(0x497c60e3, 0x7123, 0x11cf, 0xb1, 0x71, 0x0, 0xaa, 0x0, 0x57, 0x59, 0x9e);
/// <summary/>
public static readonly Guid DBPROPSET_PROVIDERCONNATTR = new(0x497c60e4, 0x7123, 0x11cf, 0xb1, 0x71, 0x0, 0xaa, 0x0, 0x57, 0x59, 0x9e);
/// <summary>Specifies whether to prompt with the Create New Data Link wizard or the Data Link Properties dialog box.</summary>
[Flags]
[PInvokeData("msdasc.h")]
public enum DBPROMPTOPTIONS
{
/// <summary/>
DBPROMPTOPTIONS_NONE = 0,
/// <summary>Deprecated. Retained for backward compatibility only.</summary>
DBPROMPTOPTIONS_WIZARDSHEET = 0x1,
/// <summary>Prompt with Data Link Properties dialog box.</summary>
DBPROMPTOPTIONS_PROPERTYSHEET = 0x2,
/// <summary/>
DBPROMPTOPTIONS_BROWSEONLY = 0x8,
/// <summary>
/// Do not prompt for provider selection. Valid only if *ppDataSource is a pointer to an existing data source object. Setting this
/// flag without specifying a valid data source object in ppDataSource on input returns the error E_INVALIDARG.
/// </summary>
DBPROMPTOPTIONS_DISABLE_PROVIDER_SELECTION = 0x10,
/// <summary>
/// Disables the "Allow Saving password" checkbox. When set, the value of the property DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO is set
/// to VARIANT_FALSE on the provider.
/// </summary>
DBPROMPTOPTIONS_DISABLESAVEPASSWORD = 0x20
}
/// <summary>Types of providers to display in the Provider selection tab</summary>
[PInvokeData("msdasc.h")]
public enum DBSOURCETYPE : uint
{
/// <summary>OLE DB tabular data provider</summary>
DBSOURCETYPE_DATASOURCE_TDP = 1,
/// <summary/>
DBSOURCETYPE_ENUMERATOR,
/// <summary>OLE DB multidimensional data provider</summary>
DBSOURCETYPE_DATASOURCE_MDP,
/// <summary/>
DBSOURCETYPE_BINDER,
}
/// <summary>
/// <para>
/// Use the <c>IDataInitialize</c> interface to create a data source object using a connection string. You can also retrieve a connection
/// string from an existing data source object.
/// </para>
/// <para>
/// To build a connection string, use the prompting user interface available through the IDBPromptInitialize interface and then use
/// <c>IDataInitialize</c> to get a data source object based on that connection string.
/// </para>
/// <para>For more information, see Creating Data Source Objects.</para>
/// </summary>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms714296(v=vs.85)
[PInvokeData("msdasc.h")]
[ComImport, Guid("2206CCB1-19C1-11D1-89E0-00C04FD7A829"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(MSDAINITIALIZE))]
public interface IDataInitialize
{
/// <summary>Given a connection string, instantiates and returns an uninitialized data source object.</summary>
/// <param name="pUnkOuter">
/// A pointer to the controlling <c>IUnknown</c> interface if the data source object is being created as a part of an aggregate;
/// otherwise, it is a null pointer.
/// </param>
/// <param name="dwClsCtx">
/// CLSCTX values. CLSCTX_ALL, CLSCTX_SERVER, and CLSCTX_INPROC_SERVER are acceptable values, but the service components will always
/// attempt to load the provider in-process. Ignored if *ppDataSource is not NULL.
/// </param>
/// <param name="pwszInitializationString">
/// <para>
/// A pointer to a connection string containing the information to be used for creating and setting initialization properties on a
/// data source object. Initialization properties are those in DBPROPSET_DBINIT, as well as provider-specific properties. If
/// pwszInitializationString is NULL, an instance of the OLE DB provider for ODBC data is returned with default properties set.
/// </para>
/// <para>
/// When run in a 32-bit application, if pwszInitializationString is NULL, an instance of the OLE DB provider for ODBC data is
/// returned with default properties set.
/// </para>
/// <para>
/// When run in a 64-bit application, if pwszInitializationString is NULL, an instance of the SQLOLEDB provider is returned with
/// default properties set.
/// </para>
/// </param>
/// <param name="riid">The requested IID for the data source object returned in *ppDataSource.</param>
/// <param name="ppDataSource">
/// <para>A pointer to a data source object.</para>
/// <para>
/// If *ppDataSource is null on entry, <c>IDataInitialize::GetDataSource</c> generates a new data source object based on the
/// information in pwszInitializationString and returns a pointer to that data source object in *ppDataSource.
/// </para>
/// <para>
/// When run in a 32-bit application, if *ppDataSource is null and no provider is specified in pwszInitializationString, OLE DB Core
/// Services returns a data source instance of OLE DB Provider for ODBC.
/// </para>
/// <para>
/// When run in a 64-bit application, if *ppDataSource is null and no provider is specified in pwszInitializationString, OLE DB Core
/// Services returns a data source instance of SQLOLEDB.
/// </para>
/// <para>
/// If *ppDataSource is null and no provider is specified in pwszInitializationString, the data source object will be defaulted to
/// the OLE DB Provider for ODBC.
/// </para>
/// <para>
/// If *ppDataSource is non-null and no provider is specified in pwszInitializationString, the data source specified by *ppDataSource
/// will be used.
/// </para>
/// <para>
/// If *ppDataSource is non-null on entry and a provider is specified in pwszInitializationString,
/// <c>IDataInitialize::GetDataSource</c> checks to see whether the specified provider matches the data source object passed in
/// *ppDataSource. If so, <c>GetDataSource</c> sets the specified properties on the existing data source object. If not,
/// <c>GetDataSource</c> returns an error and leaves *ppDataSource untouched.
/// </para>
/// </param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The method succeeded.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_NOINTERFACE The data source did not support the interface specified in riid.</para>
/// <para>riid was IID_NULL.</para>
/// <para>*ppDataSource was not null and did not indicate an OLE DB data source object.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_UNEXPECTED The data source object cannot return the requested interface because the data source object is not initialized.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// DB_E_MISMATCHEDPROVIDER The data source object specified by *ppDataSource did not match the data source object specified in pwszInitializationString.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// DB_E_NOAGGREGATION pwszInitializationString specified a provider, pUnkOuter was not a null pointer, and riid was something other
/// than <c>IID_IUnknown</c>.
/// </para>
/// <para>pwszInitializationString specified a provider, pUnkOuter was not a null pointer, and the provider does not support aggregation.</para>
/// <para>dwClsCtx required out-of-process operation, which is not supported.</para>
/// <para>The provider does not support in-process operation and cannot be aggregated.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_INVALIDARG pwszInitializationString specified a provider, and dwClsCtx was not a valid value.</para>
/// <para>ppDataSource was a null pointer.</para>
/// <para>
/// *ppDataSource and pUnkOuter were both non-null. *ppDataSource cannot be aggregated in *pUnkOuter because it has already been created.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>REGDB_E_CLASSNOTREG The provider indicated in pwszInitializationString was not found.</para>
/// <para>dwClsCtx indicated a server type not supported by the provider specified in pwszInitializationString.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_ERRORSOCCURRED A property specified in pwszInitializationString was not supported by the provider.</para>
/// <para>Properties were specified in pwszInitializationString but *ppDataSource indicated a data source that was already initialized.</para>
/// <para>
/// A property specified in pwszInitializationString was a read-only property, and the property was not set to its default value.
/// </para>
/// <para>It was not possible to set a property specified in pwszInitializationString.</para>
/// <para>One or more properties specified in pwszInitializationString conflicted with an existing property or with one another.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_BADINITSTRING A property or value specified in pwszInitializationString was invalid or not supported by the provider.</para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms725368(v=vs.85)
void GetDataSource([In, MarshalAs(UnmanagedType.IUnknown)] object? pUnkOuter, CLSCTX dwClsCtx, string? pwszInitializationString,
in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] ref object? ppDataSource);
/// <summary>Given a data source object, returns a connection string.</summary>
/// <param name="pDataSource">A pointer to a data source object.</param>
/// <param name="fIncludePassword">
/// Whether or not to include the password property, if specified, in the returned initialization string. If
/// DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO is set to VARIANT_FALSE, the password is not returned, even if fIncludePassword is true.
/// To include the password in the returned initialization string, consumers should make sure that
/// DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO is set to VARIANT_TRUE.
/// </param>
/// <returns>Returned connection string containing information necessary to re-create the data source object and current properties.</returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms714195(v=vs.85)
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetInitializationString([In, MarshalAs(UnmanagedType.IUnknown)] object? pDataSource, BOOLEAN fIncludePassword);
/// <summary>Creates a data source object; analogous to <c>CoCreateInstance</c>.</summary>
/// <param name="clsidProvider">The CLSID of the provider to instantiate.</param>
/// <param name="pUnkOuter">
/// A pointer to the controlling <c>IUnknown</c> interface if the data source object is being created as a part of an aggregate;
/// otherwise, it is a null pointer.
/// </param>
/// <param name="dwClsCtx">
/// CLSCTX values. CLSCTX_ALL, CLSCTX_SERVER, and CLSCTX_INPROC_SERVER are acceptable values, but the service components will always
/// attempt to load the provider in-process. Ignored if *ppDataSource is not NULL.
/// </param>
/// <param name="pwszReserved">Reserved for future use; must be NULL.</param>
/// <param name="riid">Interface requested on the data source.</param>
/// <param name="ppDataSource">A pointer to memory in which to return the interface pointer on the newly created data source.</param>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723098(v=vs.85) HRESULT CreateDBInstance( REFCLSID
// clsidProvider, IUnknown * pUnkOuter, DWORD dwClsCtx, LPOLESTR pwszReserved, REFIID riid, IUnknown ** ppDataSource);
void CreateDBInstance(in Guid clsidProvider, [In, Optional, MarshalAs(UnmanagedType.IUnknown)] object? pUnkOuter, CLSCTX dwClsCtx,
[In, Optional] string? pwszReserved, in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object? ppDataSource);
/// <summary>Creates a data source object; analogous to <c>CoCreateInstanceEx</c>.</summary>
/// <param name="clsidProvider">The CLSID of the provider to instantiate.</param>
/// <param name="pUnkOuter">
/// A pointer to the controlling <c>IUnknown</c> interface if the data source object is being created as a part of an aggregate;
/// otherwise, it is a null pointer.
/// </param>
/// <param name="dwClsCtx">
/// CLSCTX values. CLSCTX_ALL, CLSCTX_SERVER, and CLSCTX_INPROC_SERVER are acceptable values, but the service components will always
/// attempt to load the provider in-process. Ignored if *ppDataSource is not NULL.
/// </param>
/// <param name="pwszReserved">Reserved for future use; must be NULL.</param>
/// <param name="pServerInfo">Machine on which the data source objects are to be instantiated.</param>
/// <param name="cmq">Number of MULTI_QI structures in rgmqResults.</param>
/// <param name="rgmqResults [in,out]">Array of MULTI_QI structures.</param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The method succeeded.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// CO_S_NOTALLINTERFACES At least one, but not all, of the interfaces requested in the rgmqResults array were successfully retrieved.
/// </para>
/// <para>
/// The hr field of each of the MULTI_QI structures in rgmqResults indicates with S_OK or E_NOINTERFACE whether the specific
/// interface was returned.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_NOINTERFACE The data source did not support the interface specified in riid.</para>
/// <para>riid was IID_NULL.</para>
/// <para>The object indicated by clsidProvider was not an OLE DB provider.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_UNEXPECTED The data source object cannot return the requested interface because the data source object is not initialized.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_NOAGGREGATION pUnkOuter was not a null pointer, and riid was something other than <c>IID_IUnknown</c>.</para>
/// <para>pUnkOuter was not a null pointer, and the provider does not support aggregation.</para>
/// <para>dwClsCtx required out-of-process operation, which is not supported.</para>
/// <para>The provider does not support in-process operation and cannot be aggregated.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_INVALIDARG dwClsCtx was not a valid value.</para>
/// <para>ppDataSource was a null pointer.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>REGDB_E_CLASSNOTREG The provider indicated by clsidProvider was not found.</para>
/// <para>dwClsCtx indicated a server type not supported by the provider.</para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms712946(v=vs.85) HRESULT CreateDBInstanceEx( REFCLSID
// clsidProvider, IUnknown * pUnkOuter, DWORD dwClsCtx, LPOLESTR pwszReserved, COSERVERINFO * pServerInfo, ULONG cmq, MULTI_QI * rgmqResults);
[PreserveSig]
HRESULT CreateDBInstanceEx(in Guid clsidProvider, [In, Optional, MarshalAs(UnmanagedType.IUnknown)] object? pUnkOuter, CLSCTX dwClsCtx,
[In, Optional] string? pwszReserved, in COSERVERINFO pServerInfo, uint cmq, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)] MULTI_QI[] rgmqResults);
/// <summary>Loads a connection string.</summary>
/// <param name="pwszFileName">Name of the file.</param>
/// <returns>On exit, *ppwszInitializationString will contain the connection string.</returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms713667(v=vs.85) HRESULT LoadStringFromStorage( LPCOLESTR
// pwszFileName, LPCOLESTR * ppwszInitializationString);
[return: MarshalAs(UnmanagedType.LPWStr)]
string LoadStringFromStorage([In, Optional] string? pwszFileName);
/// <summary>Writes a connection string.</summary>
/// <param name="pwszFileName">Name of the file.</param>
/// <param name="pwszInitializationString">Connection string to write.</param>
/// <param name="dwCreationDisposition">
/// Flags controlling the write operation. Same as Win32? <c>CreateFile</c> dwCreationDisposition (CREATE_NEW, CREATE_ALWAYS,
/// OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXISTING).
/// </param>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms725461(v=vs.85) HRESULT WriteStringToStorage( LPCOLESTR
// pwszFileName, LPCOLESTR pwszInitializationString, DWORD dwCreationDisposition);
void WriteStringToStorage([In, Optional] string? pwszFileName, [In, Optional] string? pwszInitializationString, Kernel32.CreationOption dwCreationDisposition);
}
/// <summary>
/// <para>
/// The <c>IDBPromptInitialize</c> interface allows the display of the data link dialog boxes programmatically. Using the data link user
/// interface, users can build a connection string dynamically or select an existing data link (.udl) file.
/// </para>
/// <para>
/// A data source object can then be obtained based on the resulting connection string or .udl file name using the IDataInitialize interface.
/// </para>
/// <para>For more information, see Creating Data Source Objects.</para>
/// </summary>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723046(v=vs.85)
[PInvokeData("msdasc.h")]
[ComImport, Guid("2206CCB0-19C1-11D1-89E0-00C04FD7A829"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(DataLinks))]
public interface IDBPromptInitialize
{
/// <summary>
/// Opens the <c>Data Link Properties</c> dialog box. Returns an uninitialized data source object with the specified properties set.
/// </summary>
/// <param name="pUnkOuter">
/// A pointer to the controlling <c>IUnknown</c> interface if the data source object is being created as a part of an aggregate;
/// otherwise, it is a null pointer.
/// </param>
/// <param name="hWndParent">
/// The parent window handle for dialog boxes to be displayed. The dialog box will always be centered within this window.
/// </param>
/// <param name="dwPromptOptions">
/// <para>Specifies whether to prompt with the <c>Create New Data Link</c> wizard or the <c>Data Link Properties</c> dialog box.</para>
/// <list type="table">
/// <listheader>
/// <description>Value</description>
/// <description>Meaning</description>
/// </listheader>
/// <item>
/// <description>DBPROMPTOPTIONS_DISABLE_PROVIDER_SELECTION</description>
/// <description>
/// Do not prompt for provider selection. Valid only if <c>*ppDataSource</c> is a pointer to an existing data source object. Setting
/// this flag without specifying a valid data source object in <c>ppDataSource</c> on input returns the error E_INVALIDARG.
/// </description>
/// </item>
/// <item>
/// <description>DBPROMPTOPTIONS_DISABLESAVEPASSWORD</description>
/// <description>
/// Disables the "Allow Saving password" checkbox. When set, the value of the property DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO is set
/// to VARIANT_FALSE on the provider.
/// </description>
/// </item>
/// <item>
/// <description>DBPROMPTOPTIONS_PROPERTYSHEET</description>
/// <description>Prompt with <c>Data Link Properties</c> dialog box.</description>
/// </item>
/// <item>
/// <description>DBPROMPTOPTIONS_WIZARDSHEET</description>
/// <description>Deprecated. Retained for backward compatibility only.</description>
/// </item>
/// </list>
/// </param>
/// <param name="cSourceTypeFilter">
/// Number of DBSOURCETYPE values in rgSourceTypeFilter. If cSourceTypeFilter is zero, the value of rgSourceTypeFilter is ignored and
/// the <c>Provider</c> selection tab will list standard tabular OLE DB providers.
/// </param>
/// <param name="rgSourceTypeFilter">
/// <para>
/// Types of providers to display in the <c>Provider</c> selection tab. Must point to a valid array of DBSOURCETYPE values. Valid
/// source types include the values described in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <description>Value</description>
/// <description>Meaning</description>
/// </listheader>
/// <item>
/// <description>DBSOURCETYPE_DATASOURCE_TDP</description>
/// <description>OLE DB tabular data provider</description>
/// </item>
/// <item>
/// <description>DBSOURCETYPE_DATASOURCE_MDP</description>
/// <description>OLE DB multidimensional data provider</description>
/// </item>
/// </list>
/// </param>
/// <param name="pwszszzProviderFilter">
/// <para>A double null-terminated string of ProgIDs.</para>
/// <para>
/// This parameter must be a null pointer or must point to a valid string. If it is non-null, the providers presented to the user
/// will be limited to those that match the providers' ProgIDs specified in pwszszzProviderFilter. If only one provider is specified,
/// the dialog is created with the connection tab displayed. If more than one provider is specified, the provider selection tab is
/// displayed first.
/// </para>
/// <para>
/// Providers specified in pwszszzProviderFilter that are not registered on the machine are ignored. If none of the providers are
/// registered, an error is returned.
/// </para>
/// </param>
/// <param name="riid">The requested interface for the data link returned in *ppDataSource.</param>
/// <param name="ppDataSource">
/// <para>A pointer to a data source object.</para>
/// <para>
/// If *ppDataSource is null on entry, <c>IDBPromptInitialize::PromptDataSource</c> generates a new data source object based on the
/// information specified by the user and returns a pointer to that data source object in *ppDataSource.
/// </para>
/// <para>
/// If *ppDataSource is non-null on entry, <c>IDBPromptInitialize::PromptDataSource</c> uses the properties returned by
/// <c>IProperties::GetProperties</c> as initial values. If the user selects a different provider, <c>PromptDataSource</c> will
/// release the original *ppDataSource and create a new data source object. On exit, *ppDataSource will be set to a pointer to the
/// interface specified by riid. If the user selects the same provider but requests a different interface by supplying a different
/// value for riid, the output value of *ppDataSource will be a pointer to the required interface on the existing data source object.
/// </para>
/// <para>
/// If *ppDataSource is non-null on entry and the call returns an error, *ppDataSource is untouched. The caller is strongly advised
/// to check the return value when calling <c>IDBPromptInitialize::PromptDataSource</c> on an existing data source object.
/// </para>
/// </param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The method succeeded.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_CANCELED The user canceled the dialog.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_NOINTERFACE The data source object did not support the interface specified in riid.</para>
/// <para>riid was IID_NULL.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_NOAGGREGATION pUnkOuter was not a null pointer, and riid was something other than <c>IID_IUnknown</c>.</para>
/// <para>pUnkOuter was not a null pointer, and the provider does not support aggregation.</para>
/// <para>pUnkOuter and *ppDataSource were both non-null.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_INVALIDARG ppDataSource was a null pointer.</para>
/// <para>cSourceTypeFilter was not zero, and rgSourceTypeFilter was a null pointer.</para>
/// <para>An element in rgSourceTypeFilter was not a valid filter.</para>
/// <para>dwPromptOptions was an invalid value.</para>
/// <para>*ppDataSource was a null pointer, and DBPROMPTOPTIONS_DISABLE_PROVIDER_SELECTION was specified in dwPromptOptions.</para>
/// <para>*ppDataSource did not refer to a valid data source object.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// DB_E_NOPROVIDERSREGISTERED No OLE DB providers of the type specified in rgSourceTypeFilter and matching the filter, if any,
/// specified in pwszszzProviderFilter were found on the machine.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_UNEXPECTED The data source object cannot return the requested interface because the data source object is not initialized.</para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms725392(v=vs.85) HRESULT PromptDataSource( IUnknown *
// pUnkOuter, HWND hWndParent, DBPROMPTOPTIONS dwPromptOptions, ULONG cSourceTypeFilter, DBSOURCETYPE * rgSourceTypeFilter, LPCOLESTR
// pwszszzProviderFilter, REFIID riid, IUnknown ** ppDataSource);
HRESULT PromptDataSource([In, Optional, MarshalAs(UnmanagedType.IUnknown)] object? pUnkOuter, HWND hWndParent, DBPROMPTOPTIONS dwPromptOptions, uint cSourceTypeFilter,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] DBSOURCETYPE[]? rgSourceTypeFilter, [In, Optional, MarshalAs(UnmanagedType.LPWStr)] string? pwszszzProviderFilter,
in Guid riid, [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object? ppDataSource);
/// <summary>
/// Opens the <c>Select Data Link</c> dialog box. Allows the user to browse and organize .udl files. Returns a fully qualified path
/// to the user-selected .udl file.
/// </summary>
/// <param name="hWndParent">
/// The parent window handle for dialog boxes to be displayed. The dialog box will always be centered within this window.
/// </param>
/// <param name="dwPromptOptions">
/// <para>Specifies the dialog box options.</para>
/// <list type="table">
/// <listheader>
/// <description>Value</description>
/// <description>Meaning</description>
/// </listheader>
/// <item>
/// <description>DBPROMPTOPTIONS_BROWSEONLY</description>
/// <description>Prevents the user from creating new data link files.</description>
/// </item>
/// </list>
/// </param>
/// <param name="pwszInitialDirectory">
/// A pointer to a string containing the initial directory for the dialog box. If NULL, the default path "&lt;Program Files\Common
/// Files&gt;\System\OLE DB\Data Links" is used. The exact value for &lt;Program Files\Common Files&gt; is system dependent. It can
/// be determined from the "CommonFilesDir" registry entry, at "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion".
/// </param>
/// <param name="pwszInitialFile">
/// A pointer to a string containing the initial file for the file name edit box of the dialog box. Wildcard characters ("*", "?")
/// may be used to form a filtering expression.
/// </param>
/// <param name="ppwszSelectedFile">
/// *ppwszSelectedFile points to a string containing the full path to the file the user selected. ppwszSelectedFile cannot be null.
/// </param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The method succeeded.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_CANCELED The user canceled the dialog.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_INVALIDARG ppwszSelectedFile was a null pointer.</para>
/// <para>dwPromptOptions was an invalid value.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>STG_E_FILENOTFOUND pwszInitialFile could not be located. The file name may be too long or contain invalid characters.</para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms722600(v=vs.85) HRESULT PromptFileName( HWND hWndParent,
// DBPROMPTOPTIONS dwPromptOptions, LPCOLESTR pwszInitialDirectory, LPCOLESTR pwszInitialFile, LPCOLESTR * ppwszSelectedFile);
HRESULT PromptFileName(HWND hWndParent, DBPROMPTOPTIONS dwPromptOptions, [In, Optional, MarshalAs(UnmanagedType.LPWStr)] string? pwszInitialDirectory,
[In, MarshalAs(UnmanagedType.LPWStr)] string pwszInitialFile, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszSelectedFile);
}
/// <summary>Creates a data source object; analogous to <c>CoCreateInstance</c>.</summary>
/// <typeparam name="T">The interface type to create.</typeparam>
/// <param name="dataInit">The <see cref="IDataInitialize"/> instance.</param>
/// <param name="clsidProvider">The CLSID of the provider to instantiate.</param>
/// <returns>The interface pointer on the newly created data source.</returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723098(v=vs.85) HRESULT CreateDBInstance( REFCLSID
// clsidProvider, IUnknown * pUnkOuter, DWORD dwClsCtx, LPOLESTR pwszReserved, REFIID riid, IUnknown ** ppDataSource);
public static T CreateDBInstance<T>(this IDataInitialize dataInit, in Guid clsidProvider) where T : class
{
dataInit.CreateDBInstance(clsidProvider, null, CLSCTX.CLSCTX_INPROC_SERVER, null, typeof(T).GUID, out var obj);
return (T)obj!;
}
/// <summary>
/// Opens the <c>Data Link Properties</c> dialog box. Returns an uninitialized data source object with the specified properties set.
/// </summary>
/// <typeparam name="T">The requested interface for the data link returned in *ppDataSource.</typeparam>
/// <param name="pi">The <see cref="IDBPromptInitialize"/> instance.</param>
/// <param name="hWndParent">
/// The parent window handle for dialog boxes to be displayed. The dialog box will always be centered within this window.
/// </param>
/// <param name="ppDataSource">
/// <para>A pointer to a data source object.</para>
/// <para>
/// If *ppDataSource is null on entry, <c>IDBPromptInitialize::PromptDataSource</c> generates a new data source object based on the
/// information specified by the user and returns a pointer to that data source object in *ppDataSource.
/// </para>
/// <para>
/// If *ppDataSource is non-null on entry, <c>IDBPromptInitialize::PromptDataSource</c> uses the properties returned by
/// <c>IProperties::GetProperties</c> as initial values. If the user selects a different provider, <c>PromptDataSource</c> will release
/// the original *ppDataSource and create a new data source object. On exit, *ppDataSource will be set to a pointer to the interface
/// specified by riid. If the user selects the same provider but requests a different interface by supplying a different value for riid,
/// the output value of *ppDataSource will be a pointer to the required interface on the existing data source object.
/// </para>
/// <para>
/// If *ppDataSource is non-null on entry and the call returns an error, *ppDataSource is untouched. The caller is strongly advised to
/// check the return value when calling <c>IDBPromptInitialize::PromptDataSource</c> on an existing data source object.
/// </para>
/// </param>
/// <param name="dwPromptOptions">
/// <para>Specifies whether to prompt with the <c>Create New Data Link</c> wizard or the <c>Data Link Properties</c> dialog box.</para>
/// <list type="table">
/// <listheader>
/// <description>Value</description>
/// <description>Meaning</description>
/// </listheader>
/// <item>
/// <description>DBPROMPTOPTIONS_DISABLE_PROVIDER_SELECTION</description>
/// <description>
/// Do not prompt for provider selection. Valid only if <c>*ppDataSource</c> is a pointer to an existing data source object. Setting this
/// flag without specifying a valid data source object in <c>ppDataSource</c> on input returns the error E_INVALIDARG.
/// </description>
/// </item>
/// <item>
/// <description>DBPROMPTOPTIONS_DISABLESAVEPASSWORD</description>
/// <description>
/// Disables the "Allow Saving password" checkbox. When set, the value of the property DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO is set to
/// VARIANT_FALSE on the provider.
/// </description>
/// </item>
/// <item>
/// <description>DBPROMPTOPTIONS_PROPERTYSHEET</description>
/// <description>Prompt with <c>Data Link Properties</c> dialog box.</description>
/// </item>
/// <item>
/// <description>DBPROMPTOPTIONS_WIZARDSHEET</description>
/// <description>Deprecated. Retained for backward compatibility only.</description>
/// </item>
/// </list>
/// </param>
/// <param name="rgSourceTypeFilter">
/// <para>
/// Types of providers to display in the <c>Provider</c> selection tab. Must point to a valid array of DBSOURCETYPE values. Valid source
/// types include the values described in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <description>Value</description>
/// <description>Meaning</description>
/// </listheader>
/// <item>
/// <description>DBSOURCETYPE_DATASOURCE_TDP</description>
/// <description>OLE DB tabular data provider</description>
/// </item>
/// <item>
/// <description>DBSOURCETYPE_DATASOURCE_MDP</description>
/// <description>OLE DB multidimensional data provider</description>
/// </item>
/// </list>
/// </param>
/// <param name="pUnkOuter">
/// A pointer to the controlling <c>IUnknown</c> interface if the data source object is being created as a part of an aggregate;
/// otherwise, it is a null pointer.
/// </param>
/// <param name="pwszszzProviderFilter">
/// <para>A double null-terminated string of ProgIDs.</para>
/// <para>
/// This parameter must be a null pointer or must point to a valid string. If it is non-null, the providers presented to the user will be
/// limited to those that match the providers' ProgIDs specified in pwszszzProviderFilter. If only one provider is specified, the dialog
/// is created with the connection tab displayed. If more than one provider is specified, the provider selection tab is displayed first.
/// </para>
/// <para>
/// Providers specified in pwszszzProviderFilter that are not registered on the machine are ignored. If none of the providers are
/// registered, an error is returned.
/// </para>
/// </param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The method succeeded.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_CANCELED The user canceled the dialog.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_NOINTERFACE The data source object did not support the interface specified in riid.</para>
/// <para>riid was IID_NULL.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>DB_E_NOAGGREGATION pUnkOuter was not a null pointer, and riid was something other than <c>IID_IUnknown</c>.</para>
/// <para>pUnkOuter was not a null pointer, and the provider does not support aggregation.</para>
/// <para>pUnkOuter and *ppDataSource were both non-null.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_INVALIDARG ppDataSource was a null pointer.</para>
/// <para>cSourceTypeFilter was not zero, and rgSourceTypeFilter was a null pointer.</para>
/// <para>An element in rgSourceTypeFilter was not a valid filter.</para>
/// <para>dwPromptOptions was an invalid value.</para>
/// <para>*ppDataSource was a null pointer, and DBPROMPTOPTIONS_DISABLE_PROVIDER_SELECTION was specified in dwPromptOptions.</para>
/// <para>*ppDataSource did not refer to a valid data source object.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// DB_E_NOPROVIDERSREGISTERED No OLE DB providers of the type specified in rgSourceTypeFilter and matching the filter, if any, specified
/// in pwszszzProviderFilter were found on the machine.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_UNEXPECTED The data source object cannot return the requested interface because the data source object is not initialized.</para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms725392(v=vs.85) HRESULT PromptDataSource( IUnknown *
// pUnkOuter, HWND hWndParent, DBPROMPTOPTIONS dwPromptOptions, ULONG cSourceTypeFilter, DBSOURCETYPE * rgSourceTypeFilter, LPCOLESTR
// pwszszzProviderFilter, REFIID riid, IUnknown ** ppDataSource);
public static HRESULT PromptDataSource<T>(this IDBPromptInitialize pi, HWND hWndParent, out T? ppDataSource,
DBPROMPTOPTIONS dwPromptOptions = DBPROMPTOPTIONS.DBPROMPTOPTIONS_PROPERTYSHEET, [In] DBSOURCETYPE[]? rgSourceTypeFilter = null,
object? pUnkOuter = null, string? pwszszzProviderFilter = null) where T : class
{
object? obj = null;
var hr = pi.PromptDataSource(pUnkOuter, hWndParent, dwPromptOptions, (uint)(rgSourceTypeFilter?.Length ?? 0), rgSourceTypeFilter, pwszszzProviderFilter, typeof(T).GUID, ref obj);
ppDataSource = (T?)obj;
return hr;
}
/// <summary>CLSID_DataLinks</summary>
[ComImport, Guid("2206CDB2-19C1-11D1-89E0-00C04FD7A829"), ClassInterface(ClassInterfaceType.None)]
public class DataLinks { }
/// <summary>CLSID_MSDAINITIALIZE</summary>
[ComImport, Guid("2206CDB0-19C1-11D1-89E0-00C04FD7A829"), ClassInterface(ClassInterfaceType.None)]
public class MSDAINITIALIZE { }
/// <summary>CLSID_OLEDB_ENUMERATOR</summary>
[ComImport, Guid("C8B522D0-5CF3-11CE-ADE5-00AA0044773D"), ClassInterface(ClassInterfaceType.None)]
public class OleDbRootEnumerator { }
/// <summary>CLSID_PDPO</summary>
[ComImport, Guid("CCB4EC60-B9DC-11D1-AC80-00A0C9034873"), ClassInterface(ClassInterfaceType.None)]
public class PDPO { }
/// <summary>CLSID_RootBinder</summary>
[ComImport, Guid("FF151822-B0BF-11D1-A80D-000000000000"), ClassInterface(ClassInterfaceType.None)]
public class RootBinder { }
/*
IService
IDataSourceLocator
*/
}

View File

@ -0,0 +1,73 @@
using System.Collections.Generic;
namespace Vanara.PInvoke;
/// <summary>Functions to help get error messages from error codes.</summary>
public static class ErrorHelper
{
private static readonly Dictionary<Type, Func<uint, string?, string>> lookupHelpers = [];
/// <summary>
/// Adds the field lookup helper for a given library. The default lookup helper uses <c>FormatMessage</c> to fetch the help string from
/// the named module.
/// </summary>
/// <param name="helper">The helper function that takes the error code and module name and returns a help message.</param>
public static void AddErrorMessageLookupFunction<TType>(Func<uint, string?, string> helper) => lookupHelpers[typeof(TType)] = helper;
/// <summary>Gets the error message associated with an error value.</summary>
/// <typeparam name="TType">The type of the type.</typeparam>
/// <typeparam name="TFieldType">The type of the field type.</typeparam>
/// <param name="id">The identifier.</param>
/// <param name="lib">
/// The library or module name to provide a helper for. This should match the <c>lib</c> param used by <see
/// cref="StaticFieldValueHash.AddFields{TType, TFieldType}(IEnumerable{ValueTuple{TFieldType, string}}, string?)"/>.
/// </param>
/// <returns>The description of the error code.</returns>
public static string GetErrorMessage<TType, TFieldType>(TFieldType id, string? lib = null) where TFieldType : struct, IComparable, IConvertible
{
if (!lookupHelpers.TryGetValue(typeof(TType), out var lookupFunc))
lookupFunc = FormatMessage;
return lookupFunc(id.ToUInt32(null), lib ?? StaticFieldValueHash.GetFieldLib<TType, TFieldType>(id));
}
/// <summary>Formats the message.</summary>
/// <param name="id">The error.</param>
/// <param name="lib">The optional library.</param>
/// <returns>The string.</returns>
private static string FormatMessage(uint id, string? lib = null)
{
var flags = lib is null ? 0x1200U /*FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM*/ : 0xA00U /*FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE*/;
HINSTANCE hInst = lib is null ? default : LoadLibraryEx(lib, default, 0x1002 /*LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_AS_DATAFILE*/);
var buf = new StringBuilder(1024);
try
{
do
{
if (0 != FormatMessage(flags, hInst, id, 0, buf, (uint)buf.Capacity, default))
return buf.ToString();
var lastError = unchecked((uint)Marshal.GetLastWin32Error());
if (lastError is Win32Error.ERROR_MR_MID_NOT_FOUND or Win32Error.ERROR_MUI_FILE_NOT_FOUND or Win32Error.ERROR_RESOURCE_TYPE_NOT_FOUND)
break;
if (lastError != Win32Error.ERROR_INSUFFICIENT_BUFFER)
((Win32Error)lastError).ThrowIfFailed();
buf.Capacity *= 2;
} while (true && buf.Capacity < 1024 * 16); // Don't go crazy
}
finally
{
if (hInst != default)
FreeLibrary(hInst);
}
return string.Empty;
}
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
private static extern int FormatMessage(uint dwFlags, HINSTANCE lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, uint nSize, IntPtr Arguments);
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeLibrary([In] HINSTANCE hLibModule);
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
private static extern HINSTANCE LoadLibraryEx([MarshalAs(UnmanagedType.LPTStr)] string lpLibFileName, HANDLE hFile, uint dwFlags);
}

View File

@ -6,9 +6,9 @@ using System.Reflection;
namespace Vanara.PInvoke;
/// <summary>Gets a static field's name from its value and caches the list for faster lookups.</summary>
public class StaticFieldValueHash
public static class StaticFieldValueHash
{
private static readonly Dictionary<(Type, Type), IDictionary<int, (string, string?)>> cache = new();
private static readonly Dictionary<(Type, Type), IDictionary<int, (string, string?)>> cache = [];
/// <summary>Adds the seqence of field values to the associated cache.</summary>
/// <typeparam name="TType">The type of the type.</typeparam>
@ -16,7 +16,7 @@ public class StaticFieldValueHash
/// <param name="fields">The list of field values and names to add.</param>
/// <param name="lib">The optional library name.</param>
public static void AddFields<TType, TFieldType>(IEnumerable<(TFieldType value, string name)> fields, string? lib = null)
where TFieldType : struct, IComparable
where TFieldType : struct, IComparable, IConvertible
{
TryGetFieldName<TType, TFieldType>(default, out _); // Load default values
var tt = (typeof(TType), typeof(TFieldType));
@ -33,7 +33,7 @@ public class StaticFieldValueHash
/// <typeparam name="TFieldType">The type of the field type.</typeparam>
/// <typeparam name="TEnum">The type of the enum to added.</typeparam>
/// <param name="lib">The optional library name.</param>
public static void AddFields<TType, TFieldType, TEnum>(string? lib = null) where TFieldType : struct, IComparable =>
public static void AddFields<TType, TFieldType, TEnum>(string? lib = null) where TFieldType : struct, IComparable, IConvertible =>
AddFields<TType, TFieldType>(Enum.GetValues(typeof(TEnum)).Cast<TFieldType>().Select(v => (v, Enum.GetName(typeof(TEnum), v)!)), lib);
/// <summary>Tries to get the name of a value's library.</summary>
@ -42,7 +42,7 @@ public class StaticFieldValueHash
/// <param name="value">The value for which to search.</param>
/// <returns>The name of the library or <see langword="null"/>.</returns>
public static string? GetFieldLib<TType, TFieldType>(TFieldType value)
where TFieldType : struct, IComparable
where TFieldType : struct, IComparable, IConvertible
{
var tt = (typeof(TType), typeof(TFieldType));
return cache.TryGetValue(tt, out var hash) && hash.TryGetValue(value.GetHashCode(), out var t) ? t.Item2 : null;
@ -55,7 +55,7 @@ public class StaticFieldValueHash
/// <param name="fieldName">On success, the name of the field.</param>
/// <returns><see langword="true"/> if the value was found, otherwise <see langword="false"/>.</returns>
public static bool TryGetFieldName<TType, TFieldType>(TFieldType value, [NotNullWhen(true)] out string? fieldName)
where TFieldType : struct, IComparable
where TFieldType : struct, IComparable, IConvertible
{
var tt = (typeof(TType), typeof(TFieldType));
if (!cache.TryGetValue(tt, out var hash))
@ -70,7 +70,7 @@ public class StaticFieldValueHash
return ret;
}
private class FIValueComp<TFieldType> : IEqualityComparer<FieldInfo> where TFieldType : struct, IComparable
private class FIValueComp<TFieldType> : IEqualityComparer<FieldInfo> where TFieldType : struct, IComparable, IConvertible
{
bool IEqualityComparer<FieldInfo>.Equals(FieldInfo? x, FieldInfo? y) =>
Comparer<TFieldType?>.Default.Compare((TFieldType?)x?.GetValue(null), (TFieldType?)y?.GetValue(null)) == 0;

View File

@ -36,7 +36,7 @@ public abstract class SafeHANDLE : SafeHandleZeroOrMinusOneIsInvalid, IEquatable
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(SafeHANDLE h1, IHandle h2) => !(h1 == h2);
public static bool operator !=(SafeHANDLE h1, IHandle? h2) => !(h1 == h2);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -48,7 +48,7 @@ public abstract class SafeHANDLE : SafeHandleZeroOrMinusOneIsInvalid, IEquatable
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(SafeHANDLE h1, IHandle h2) => h1?.Equals(h2) ?? h2 is null;
public static bool operator ==(SafeHANDLE h1, IHandle? h2) => h1?.Equals(h2) ?? h2 is null;
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>

View File

@ -619,7 +619,7 @@ public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HR
/// </summary>
/// <param name="hresult">The 32-bit raw HRESULT value.</param>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static void ThrowIfFailed(HRESULT hresult, string? message = null) => hresult.ThrowIfFailed(message);
/// <summary>
@ -628,7 +628,7 @@ public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HR
/// </summary>
/// <param name="hresult">The 32-bit raw HRESULT value.</param>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static void ThrowIfFailed(int hresult, string? message = null) => new HRESULT(hresult).ThrowIfFailed(message);
/// <summary>Compares the current object with another object of the same type.</summary>
@ -723,7 +723,7 @@ public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HR
/// </summary>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[SecurityCritical, SecuritySafeCritical]
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public void ThrowIfFailed(string? message = null)
{
var exception = GetException(message);
@ -747,7 +747,7 @@ public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HR
}
}
}
var msg = FormatMessage(unchecked((uint)_value), StaticFieldValueHash.GetFieldLib<HRESULT, int>(_value));
var msg = ErrorHelper.GetErrorMessage<HRESULT, int>(_value);
return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", _value)) + (msg == null ? "" : ": " + msg);
}
@ -790,47 +790,6 @@ public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HR
ulong IConvertible.ToUInt64(IFormatProvider? provider) => ((IConvertible)unchecked((uint)_value)).ToUInt64(provider);
/// <summary>Formats the message.</summary>
/// <param name="id">The error.</param>
/// <param name="lib">The optional library.</param>
/// <returns>The string.</returns>
internal static string FormatMessage(uint id, string? lib = null)
{
var flags = lib is null ? 0x1200U /*FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM*/ : 0xA00U /*FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE*/;
HINSTANCE hInst = lib is null ? default : LoadLibraryEx(lib, default, 0x1002 /*LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_AS_DATAFILE*/);
var buf = new StringBuilder(1024);
try
{
do
{
if (0 != FormatMessage(flags, hInst, id, 0, buf, (uint)buf.Capacity, default))
return buf.ToString();
var lastError = Win32Error.GetLastError();
if (lastError == Win32Error.ERROR_MR_MID_NOT_FOUND || lastError == Win32Error.ERROR_MUI_FILE_NOT_FOUND || lastError == Win32Error.ERROR_RESOURCE_TYPE_NOT_FOUND)
break;
if (lastError != Win32Error.ERROR_INSUFFICIENT_BUFFER)
lastError.ThrowIfFailed();
buf.Capacity *= 2;
} while (true && buf.Capacity < 1024 * 16); // Don't go crazy
}
finally
{
if (hInst != default)
FreeLibrary(hInst);
}
return string.Empty;
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
static extern int FormatMessage(uint dwFlags, HINSTANCE lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, uint nSize, IntPtr Arguments);
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool FreeLibrary([In] HINSTANCE hLibModule);
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
static extern HINSTANCE LoadLibraryEx([MarshalAs(UnmanagedType.LPTStr)] string lpLibFileName, HANDLE hFile, uint dwFlags);
}
private static int? ValueFromObj(object? obj)
{
switch (obj)

View File

@ -388,6 +388,7 @@ public partial struct NTStatus : IComparable, IComparable<NTStatus>, IEquatable<
/// </summary>
/// <param name="ntstatus">The 32-bit raw NTStatus value.</param>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static void ThrowIfFailed(int ntstatus, string? message = null) => new NTStatus(ntstatus).ThrowIfFailed(message);
/// <summary>Compares the current object with another object of the same type.</summary>
@ -461,6 +462,7 @@ public partial struct NTStatus : IComparable, IComparable<NTStatus>, IEquatable<
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[SecurityCritical]
[SecuritySafeCritical]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public void ThrowIfFailed(string? message = null)
{
var exception = GetException(message);
@ -482,7 +484,7 @@ public partial struct NTStatus : IComparable, IComparable<NTStatus>, IEquatable<
{
// Check for defined NTStatus value
StaticFieldValueHash.TryGetFieldName<NTStatus, int>(_value, out var err);
var msg = HRESULT.FormatMessage(unchecked((uint)_value));
var msg = ErrorHelper.GetErrorMessage<NTStatus, int>(_value);
return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", _value)) + (msg == null ? "" : ": " + msg);
}

View File

@ -86,12 +86,12 @@ public partial struct Win32Error : IEquatable<Win32Error>, IEquatable<uint>, ICo
/// <summary>Throws if failed.</summary>
/// <param name="err">The error.</param>
/// <param name="message">The message.</param>
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static void ThrowIfFailed(Win32Error err, string? message = null) => err.ThrowIfFailed(message);
/// <summary>Throws the last error.</summary>
/// <param name="message">The message to associate with the exception.</param>
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static void ThrowLastError(string? message = null) => GetLastError().ThrowIfFailed(message);
/// <summary>Throws the last error if the predicate delegate returns <see langword="true"/>.</summary>
@ -100,6 +100,7 @@ public partial struct Win32Error : IEquatable<Win32Error>, IEquatable<uint>, ICo
/// <param name="valueIsFailure">The delegate which returns <see langword="true"/> on failure.</param>
/// <param name="message">The message.</param>
/// <returns>The <paramref name="value"/> passed in on success.</returns>
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static T ThrowLastErrorIf<T>(T value, Func<T, bool> valueIsFailure, string? message = null)
{
if (valueIsFailure(value))
@ -110,22 +111,25 @@ public partial struct Win32Error : IEquatable<Win32Error>, IEquatable<uint>, ICo
/// <summary>Throws the last error if the function returns <see langword="false"/>.</summary>
/// <param name="value">The value to check.</param>
/// <param name="message">The message.</param>
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static bool ThrowLastErrorIfFalse(bool value, string? message = null) => ThrowLastErrorIf(value, v => !v, message);
/// <summary>Throws the last error if the value is an invalid handle.</summary>
/// <param name="value">The SafeHandle to check.</param>
/// <param name="message">The message.</param>
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static T ThrowLastErrorIfInvalid<T>(T value, string? message = null) where T : SafeHandle => ThrowLastErrorIf(value, v => v.IsInvalid, message);
/// <summary>Throws the last error if the value is a NULL pointer (IntPtr.Zero).</summary>
/// <param name="value">The pointer to check.</param>
/// <param name="message">The message.</param>
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static IntPtr ThrowLastErrorIfNull(IntPtr value, string? message = null) => ThrowLastErrorIf(value, v => v == IntPtr.Zero, message);
/// <summary>Throws if the last error failed, unless the error is the specified value.</summary>
/// <param name="exception">The failure code to ignore.</param>
/// <param name="message">The message to associate with the exception.</param>
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public static void ThrowLastErrorUnless(Win32Error exception, string? message = null) => GetLastError().ThrowUnless(exception, message);
/// <summary>Compares the current object with another object of the same type.</summary>
@ -187,7 +191,7 @@ public partial struct Win32Error : IEquatable<Win32Error>, IEquatable<uint>, ICo
/// <summary>Throws if failed.</summary>
/// <param name="message">The message.</param>
/// <exception cref="Win32Exception"></exception>
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerHidden, System.Diagnostics.StackTraceHidden]
public void ThrowIfFailed(string? message = null)
{
if (value != ERROR_SUCCESS) throw GetException(message)!;
@ -211,7 +215,7 @@ public partial struct Win32Error : IEquatable<Win32Error>, IEquatable<uint>, ICo
public override string ToString()
{
_ = StaticFieldValueHash.TryGetFieldName<Win32Error, uint>(value, out var err);
var msg = HRESULT.FormatMessage(value);
var msg = ErrorHelper.GetErrorMessage<Win32Error, uint>(value);
return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", value)) + (msg == null ? "" : ": " + msg);
}

View File

@ -437,6 +437,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vanara.PInvoke.Odbc32", "PI
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Odbc32", "UnitTests\PInvoke\Odbc32\Odbc32.csproj", "{94724746-9D66-45E5-8EF1-419E29C6DF12}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vanara.PInvoke.OleDb", "PInvoke\OleDb\Vanara.PInvoke.OleDb.csproj", "{2DCB4898-C95C-4529-9655-E087171B44DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -3829,6 +3831,24 @@ Global
{94724746-9D66-45E5-8EF1-419E29C6DF12}.Release|x64.Build.0 = Release|x64
{94724746-9D66-45E5-8EF1-419E29C6DF12}.Release|x86.ActiveCfg = Release|x86
{94724746-9D66-45E5-8EF1-419E29C6DF12}.Release|x86.Build.0 = Release|x86
{2DCB4898-C95C-4529-9655-E087171B44DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DCB4898-C95C-4529-9655-E087171B44DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DCB4898-C95C-4529-9655-E087171B44DC}.Debug|x64.ActiveCfg = Debug|x64
{2DCB4898-C95C-4529-9655-E087171B44DC}.Debug|x64.Build.0 = Debug|x64
{2DCB4898-C95C-4529-9655-E087171B44DC}.Debug|x86.ActiveCfg = Debug|x86
{2DCB4898-C95C-4529-9655-E087171B44DC}.Debug|x86.Build.0 = Debug|x86
{2DCB4898-C95C-4529-9655-E087171B44DC}.DebugNoTests|Any CPU.ActiveCfg = Debug|Any CPU
{2DCB4898-C95C-4529-9655-E087171B44DC}.DebugNoTests|Any CPU.Build.0 = Debug|Any CPU
{2DCB4898-C95C-4529-9655-E087171B44DC}.DebugNoTests|x64.ActiveCfg = Debug|x64
{2DCB4898-C95C-4529-9655-E087171B44DC}.DebugNoTests|x64.Build.0 = Debug|x64
{2DCB4898-C95C-4529-9655-E087171B44DC}.DebugNoTests|x86.ActiveCfg = Debug|x86
{2DCB4898-C95C-4529-9655-E087171B44DC}.DebugNoTests|x86.Build.0 = Debug|x86
{2DCB4898-C95C-4529-9655-E087171B44DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DCB4898-C95C-4529-9655-E087171B44DC}.Release|Any CPU.Build.0 = Release|Any CPU
{2DCB4898-C95C-4529-9655-E087171B44DC}.Release|x64.ActiveCfg = Release|x64
{2DCB4898-C95C-4529-9655-E087171B44DC}.Release|x64.Build.0 = Release|x64
{2DCB4898-C95C-4529-9655-E087171B44DC}.Release|x86.ActiveCfg = Release|x86
{2DCB4898-C95C-4529-9655-E087171B44DC}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -4025,6 +4045,7 @@ Global
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
{ED1BF632-4ACD-4B6B-9F27-C6DE86E00D37} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
{94724746-9D66-45E5-8EF1-419E29C6DF12} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
{2DCB4898-C95C-4529-9655-E087171B44DC} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}