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