using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using Vanara.Extensions; using Vanara.InteropServices; namespace Vanara.PInvoke { /// Platform invokable enumerated types, constants and functions from ole32.h public static partial class Ole32 { /// Specifies the destination context, which is the process in which the unmarshaling is to be done. [PInvokeData("wtypesbase.h")] public enum MSHCTX { /// The unmarshaling process is local and has shared memory access with the marshaling process. MSHCTX_LOCAL, /// The unmarshaling process does not have shared memory access with the marshaling process. MSHCTX_NOSHAREDMEM, /// /// The unmarshaling process is on a different computer. The marshaling code cannot assume that a particular piece of /// application code is installed on that computer. /// MSHCTX_DIFFERENTMACHINE, /// The unmarshaling will be done in another apartment in the same process. MSHCTX_INPROC, /// Create a new context in the current apartment. MSHCTX_CROSSCTX, /// Reserved MSHCTX_RESERVED1, } /// Specifies why the marshaling is to be done. [PInvokeData("wtypesbase.h")] public enum MSHLFLAGS { /// /// The marshaling is occurring because an interface pointer is being passed from one process to another. This is the normal /// case. The data packet produced by the marshaling process will be unmarshaled in the destination process. The marshaled data /// packet can be unmarshaled just once, or not at all. If the receiver unmarshals the data packet successfully, the /// CoReleaseMarshalData function is automatically called on the data packet as part of the unmarshaling process. If the /// receiver does not or cannot unmarshal the data packet, the sender must call CoReleaseMarshalData on the data packet. /// MSHLFLAGS_NORMAL, /// /// The marshaling is occurring because the data packet is to be stored in a globally accessible table from which it can be /// unmarshaled one or more times, or not at all. The presence of the data packet in the table counts as a strong reference to /// the interface being marshaled, meaning that it is sufficient to keep the object alive. When the data packet is removed from /// the table, the table implementer must call the CoReleaseMarshalData function on the data packet. /// /// MSHLFLAGS_TABLESTRONG is used by the RegisterDragDrop function when registering a window as a drop target. This keeps the /// window registered as a drop target no matter how many times the end user drags across the window. The RevokeDragDrop /// function calls CoReleaseMarshalData. /// /// MSHLFLAGS_TABLESTRONG, /// /// The marshaling is occurring because the data packet is to be stored in a globally accessible table from which it can be /// unmarshaled one or more times, or not at all. However, the presence of the data packet in the table acts as a weak reference /// to the interface being marshaled, meaning that it is not sufficient to keep the object alive. When the data packet is /// removed from the table, the table implementer must call the CoReleaseMarshalData function on the data packet. /// /// MSHLFLAGS_TABLEWEAK is typically used when registering an object in the running object table (ROT). This prevents the /// object's entry in the ROT from keeping the object alive in the absence of any other connections. See /// IRunningObjectTable::Register for more information. /// /// MSHLFLAGS_TABLEWEAK, /// /// Adding this flag to an original object marshaling (as opposed to marshaling a proxy) will disable the ping protocol for that object. /// MSHLFLAGS_NOPING, /// Reserved MSHLFLAGS_RESERVED1, /// Reserved MSHLFLAGS_RESERVED2, /// Reserved MSHLFLAGS_RESERVED3, /// Reserved MSHLFLAGS_RESERVED4, } /// /// Indicates whether the method should try to return a name in the pwcsName member of the STATSTG structure. The values are used in /// the ILockBytes::Stat, IStorage::Stat, and IStream::Stat methods to save memory when the pwcsName member is not required. /// [PInvokeData("WTypes.h", MSDNShortId = "aa380316")] public enum STATFLAG { /// Requests that the statistics include the pwcsName member of the STATSTG structure. STATFLAG_DEFAULT = 0, /// /// Requests that the statistics not include the pwcsName member of the STATSTG structure. If the name is omitted, there is no /// need for the ILockBytes::Stat, IStorage::Stat, and IStream::Stat methods to allocate and free memory for the string value of /// the name, therefore the method reduces time and resources used in an allocation and free operation. /// STATFLAG_NONAME = 1, /// Not implemented. STATFLAG_NOOPEN = 2 } /// Specify the conditions for performing the commit operation in the IStorage::Commit and IStream::Commit methods. [PInvokeData("WTypes.h", MSDNShortId = "aa380320")] public enum STGC { /// /// You can specify this condition with STGC_CONSOLIDATE, or some combination of the other three flags in this list of elements. /// Use this value to increase the readability of code. /// STGC_DEFAULT = 0, /// /// The commit operation can overwrite existing data to reduce overall space requirements. This value is not recommended for /// typical usage because it is not as robust as the default value. In this case, it is possible for the commit operation to /// fail after the old data is overwritten, but before the new data is completely committed. Then, neither the old version nor /// the new version of the storage object will be intact. /// You can use this value in the following cases: /// /// /// The user is willing to risk losing the data. /// /// /// The low-memory save sequence will be used to safely save the storage object to a smaller file. /// /// /// /// A previous commit returned STG_E_MEDIUMFULL, but overwriting the existing data would provide enough space to commit changes /// to the storage object. /// /// /// /// /// Be aware that the commit operation verifies that adequate space exists before any overwriting occurs. Thus, even with this /// value specified, if the commit operation fails due to space requirements, the old data is safe. It is possible, however, for /// data loss to occur with the STGC_OVERWRITE value specified if the commit operation fails for any reason other than lack of /// disk space. /// /// STGC_OVERWRITE = 1, /// /// Prevents multiple users of a storage object from overwriting each other's changes. The commit operation occurs only if there /// have been no changes to the saved storage object because the user most recently opened it. Thus, the saved version of the /// storage object is the same version that the user has been editing. If other users have changed the storage object, the /// commit operation fails and returns the STG_E_NOTCURRENT value. To override this behavior, call the IStorage::Commit or /// IStream::Commit method again using the STGC_DEFAULT value. /// STGC_ONLYIFCURRENT = 2, /// /// Commits the changes to a write-behind disk cache, but does not save the cache to the disk. In a write-behind disk cache, the /// operation that writes to disk actually writes to a disk cache, thus increasing performance. The cache is eventually written /// to the disk, but usually not until after the write operation has already returned. The performance increase comes at the /// expense of an increased risk of losing data if a problem occurs before the cache is saved and the data in the cache is lost. /// /// If you do not specify this value, then committing changes to root-level storage objects is robust even if a disk cache is /// used. The two-phase commit process ensures that data is stored on the disk and not just to the disk cache. /// /// STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 4, /// /// Windows 2000 and Windows XP: Indicates that a storage should be consolidated after it is committed, resulting in a smaller /// file on disk. This flag is valid only on the outermost storage object that has been opened in transacted mode. It is not /// valid for streams. The STGC_CONSOLIDATE flag can be combined with any other STGC flags. /// STGC_CONSOLIDATE = 8 } /// Indicate whether a storage element is to be moved or copied. They are used in the IStorage::MoveElementTo method. [PInvokeData("WTypes.h", MSDNShortId = "aa380336")] public enum STGMOVE { /// Indicates that the method should move the data from the source to the destination. STGMOVE_MOVE = 0, /// /// Indicates that the method should copy the data from the source to the destination. A copy is the same as a move except that /// the source element is not removed after copying the element to the destination. Copying an element on top of itself is undefined. /// STGMOVE_COPY = 1, /// Not implemented. STGMOVE_SHALLOWCOPY = 2 } /// Specifies a mapping for a class ID. /// /// The TYSPEC enumeration and uCLSSPEC union provide mappings to a class ID. Note that TYSPEC_CLSID is the only supported value. /// // https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ne-wtypes-tyspec typedef enum tagTYSPEC { TYSPEC_CLSID, TYSPEC_FILEEXT, // TYSPEC_MIMETYPE, TYSPEC_FILENAME, TYSPEC_PROGID, TYSPEC_PACKAGENAME, TYSPEC_OBJECTID } TYSPEC; [PInvokeData("wtypes.h", MSDNShortId = "f2972300-5a95-43e3-b2d1-cd8f30d14d1d")] public enum TYSPEC { /// A CLSID. TYSPEC_CLSID, /// A file name extension. TYSPEC_FILEEXT, /// A MIME type. TYSPEC_MIMETYPE, /// A file name. TYSPEC_FILENAME, /// A PROGID. TYSPEC_PROGID, /// A package name. TYSPEC_PACKAGENAME, /// An object ID. TYSPEC_OBJECTID, } /// Equivalent to , but cast to . [Flags] [PInvokeData("Wtypes.h", MSDNShortId = "ms221127")] public enum VARTYPE : ushort { /// Not specified. [CorrespondingType(typeof(object))] VT_EMPTY = 0, /// Null. [CorrespondingType(typeof(DBNull))] VT_NULL = 1, /// A 2-byte integer. [CorrespondingType(typeof(short))] VT_I2 = 2, /// A 4-byte integer. [CorrespondingType(typeof(int))] VT_I4 = 3, /// A 4-byte real. [CorrespondingType(typeof(float))] VT_R4 = 4, /// A 8-byte real. [CorrespondingType(typeof(double))] VT_R8 = 5, /// Currency [CorrespondingType(typeof(decimal))] VT_CY = 6, /// A date. [CorrespondingType(typeof(DateTime))] VT_DATE = 7, /// A string. [CorrespondingType(typeof(string))] VT_BSTR = 8, /// An IDispatch pointer. [CorrespondingType(typeof(object))] VT_DISPATCH = 9, /// An SCODE value. [CorrespondingType(typeof(Win32Error))] VT_ERROR = 10, /// A Boolean value. True is -1 and false is 0. [CorrespondingType(typeof(bool))] VT_BOOL = 11, /// A variant pointer. [CorrespondingType(typeof(object))] VT_VARIANT = 12, /// An IUnknown pointer. [CorrespondingType(typeof(object))] VT_UNKNOWN = 13, /// A 16-byte fixed-point value. [CorrespondingType(typeof(decimal))] VT_DECIMAL = 14, /// A character. [CorrespondingType(typeof(sbyte))] VT_I1 = 16, /// An unsigned character. [CorrespondingType(typeof(byte))] VT_UI1 = 17, /// An unsigned short. [CorrespondingType(typeof(ushort))] VT_UI2 = 18, /// An unsigned long. [CorrespondingType(typeof(uint))] VT_UI4 = 19, /// A 64-bit integer. [CorrespondingType(typeof(long))] VT_I8 = 20, /// A 64-bit unsigned integer. [CorrespondingType(typeof(ulong))] VT_UI8 = 21, /// An integer. [CorrespondingType(typeof(int))] VT_INT = 22, /// An unsigned integer. [CorrespondingType(typeof(uint))] VT_UINT = 23, /// A C-style void. [CorrespondingType(typeof(IntPtr))] VT_VOID = 24, /// A C-style void. [CorrespondingType(typeof(double))] VT_HRESULT = 25, /// A pointer type. [CorrespondingType(typeof(IntPtr))] VT_PTR = 26, /// A safe array. Use VT_ARRAY in VARIANT. VT_SAFEARRAY = 27, /// A C-style array. VT_CARRAY = 28, /// A user-defined type. [CorrespondingType(typeof(IntPtr))] VT_USERDEFINED = 29, /// A null-terminated string. [CorrespondingType(typeof(string))] VT_LPSTR = 30, /// A wide null-terminated string. [CorrespondingType(typeof(string))] VT_LPWSTR = 31, /// A user-defined type. [CorrespondingType(typeof(IntPtr))] VT_RECORD = 36, /// A FILETIME value. [CorrespondingType(typeof(System.Runtime.InteropServices.ComTypes.FILETIME))] VT_FILETIME = 64, /// Length-prefixed bytes. [CorrespondingType(typeof(BLOB))] VT_BLOB = 65, /// The name of the stream follows. [CorrespondingType(typeof(IStream))] VT_STREAM = 66, /// The name of the storage follows. [CorrespondingType(typeof(IStorage))] VT_STORAGE = 67, /// The stream contains an object. [CorrespondingType(typeof(IStream))] VT_STREAMED_OBJECT = 68, /// The storage contains an object. [CorrespondingType(typeof(IStorage))] VT_STORED_OBJECT = 69, /// The blob contains an object. VT_BLOB_OBJECT = 70, /// A clipboard format. [CorrespondingType(typeof(CLIPDATA))] VT_CF = 71, /// A class ID (GUID). [CorrespondingType(typeof(Guid))] VT_CLSID = 72, /// A stream with a GUID version. VT_VERSIONED_STREAM = 73, /// A simple counted array. VT_VECTOR = 0x1000, /// A SAFEARRAY pointer. VT_ARRAY = 0x2000, /// A void pointer for local use. VT_BYREF = 0x4000, } /// Gets the .NET runtime type which corresponds to the . /// The enumeration value to evaluate. /// /// The corresponding .NET runtime type. /// /// If specifies or , the return type is an /// array of the element type. /// /// /// If specifies and the element type is a value type, the return type is a /// pointer to the element type. /// /// public static Type GetCorrespondingType(this VARTYPE vt) { var elemVT = vt & ~(VARTYPE)0xF000; var specVT = vt & (VARTYPE)0xF000; var type = CorrespondingTypeAttribute.GetCorrespondingTypes(elemVT).FirstOrDefault(); if (type is null || elemVT == 0) return null; // Change type if by reference if (specVT.IsFlagSet(VARTYPE.VT_BYREF) && type.IsValueType) type = type.MakePointerType(); // Change type if vector if (specVT.IsFlagSet(VARTYPE.VT_VECTOR) || specVT.IsFlagSet(VARTYPE.VT_ARRAY)) type = type.MakeArrayType(); return type; } /// Contains an operating system platform and processor architecture. // https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ns-wtypes-csplatform typedef struct tagCSPLATFORM { DWORD dwPlatformId; // DWORD dwVersionHi; DWORD dwVersionLo; DWORD dwProcessorArch; } CSPLATFORM; [PInvokeData("wtypes.h", MSDNShortId = "e9ffa8ba-98a2-431c-a069-20ed4a45e6f8")] [StructLayout(LayoutKind.Sequential)] public struct CSPLATFORM { /// The operating system platform. See the dwPlatformId member of OSVERSIONINFO. public PlatformID dwPlatformId; /// The major version of the operating system. public uint dwVersionHi; /// The minor version of the operating system. public uint dwVersionLo; /// The processor architecture. See the wProcessorArchitecture member of SYSTEM_INFO. public ProcessorArchitecture dwProcessorArch; } /// Contains a list of attributes used to look up a class implementation. // https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ns-wtypes-querycontext typedef struct tagQUERYCONTEXT { DWORD // dwContext; CSPLATFORM Platform; LCID Locale; DWORD dwVersionHi; DWORD dwVersionLo; } QUERYCONTEXT; [PInvokeData("wtypes.h", MSDNShortId = "5d6a17e1-dcdd-4691-aec2-f63dbcb26027")] [StructLayout(LayoutKind.Sequential)] public struct QUERYCONTEXT { /// The execution context. public CLSCTX dwContext; /// The operating system platform and processor architecture. For more information, see CSPLATFORM. public CSPLATFORM Platform; /// The locale identifier. For more information, see Language Identifier Constants and Strings. public LCID Locale; /// The high version number. public uint dwVersionHi; /// The low version number. public uint dwVersionLo; } /// Specifies a mapping for a class ID. /// /// The TYSPEC enumeration and uCLSSPEC union provide mappings to a class ID. Note that TYSPEC_CLSID is the only supported value. /// // https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ne-wtypes-tyspec typedef enum tagTYSPEC { TYSPEC_CLSID, TYSPEC_FILEEXT, // TYSPEC_MIMETYPE, TYSPEC_FILENAME, TYSPEC_PROGID, TYSPEC_PACKAGENAME, TYSPEC_OBJECTID } TYSPEC; [PInvokeData("wtypes.h", MSDNShortId = "f2972300-5a95-43e3-b2d1-cd8f30d14d1d")] [StructLayout(LayoutKind.Sequential)] public struct uCLSSPEC { /// The union type. public TYSPEC tyspec; /// The union. public SpecUnion tagged_union; /// The union. [StructLayout(LayoutKind.Explicit)] public struct SpecUnion { /// [FieldOffset(0)] public Guid clsid; /// [FieldOffset(0)] public StrPtrUni pFileExt; /// [FieldOffset(0)] public StrPtrUni pMimeType; /// [FieldOffset(0)] public StrPtrUni pProgId; /// [FieldOffset(0)] public StrPtrUni pFileName; /// [FieldOffset(0)] public BYNAME ByName; /// [FieldOffset(0)] public BYOBJECTID ByObjectId; /// public struct BYNAME { /// public StrPtrUni pPackageName; /// public Guid PolicyId; } /// public struct BYOBJECTID { /// public Guid ObjectId; /// public Guid PolicyId; } } } } }