Skip to content

Instantly share code, notes, and snippets.

@rickbrew
Created November 28, 2021 04:12
Show Gist options
  • Save rickbrew/2d54728ca99fe91476e01db622d39a8c to your computer and use it in GitHub Desktop.
Save rickbrew/2d54728ca99fe91476e01db622d39a8c to your computer and use it in GitHub Desktop.
using System;
using System.Runtime.InteropServices;
namespace PaintDotNet.Interop;
// This contains items that are missing from TerraFX.Interop.Windows.dll
internal static unsafe class Windows2
{
public static HRESULT InitPropVariantFromBoolean(bool fVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_BOOL;
ppropvar->boolVal = fVal ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromBooleanVector(
BOOL* prgf,
uint cElems,
PROPVARIANT* ppropvar);
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromBuffer(
void* pv,
uint cb,
PROPVARIANT* ppropvar);
// Not in propvarutil.h
public static HRESULT InitPropVariantFromDate(double date, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->date = date;
ppropvar->vt = (ushort)VT_DATE;
return S_OK;
}
// Not in propvarutil.h
public static HRESULT InitPropVariantFromDecimal(DECIMAL* pDecimal, PROPVARIANT* ppropvar)
{
if (pDecimal == null || ppropvar == null)
{
return E_POINTER;
}
// As per documentation, we must set decVal first, then set vt
ppropvar->decVal = *pDecimal;
ppropvar->vt = (ushort)VT_DECIMAL;
return S_OK;
}
public static HRESULT InitPropVariantFromDouble(double dblVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_R8;
ppropvar->dblVal = dblVal;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromDoubleVector(
double* prgn,
uint cElems,
PROPVARIANT* ppropvar);
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromFileTime(
FILETIME* pftIn,
PROPVARIANT* ppropVar);
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromFileTimeVector(
FILETIME* prgft,
uint cElems,
PROPVARIANT* ppropvar);
// Not in propvarutil.h
public static HRESULT InitPropVariantFromFloat(float fltVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_R4;
ppropvar->fltVal = fltVal;
return S_OK;
}
// Not in propvarutil.h
public static HRESULT InitPropVariantFromFloatVector(
float* prgn,
uint cElems,
PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
nuint cbElems = (nuint)sizeof(float) * cElems;
float* pElems = (float*)CoTaskMemAlloc(cbElems);
if (pElems == null)
{
return E_OUTOFMEMORY;
}
if (prgn != null)
{
BufferUtil.Copy(pElems, prgn, cbElems);
}
else
{
BufferUtil.Fill(pElems, 0, cbElems);
}
ppropvar->vt = (ushort)(VT_VECTOR | VT_R4);
ppropvar->caflt.cElems = cElems;
ppropvar->caflt.pElems = pElems;
return S_OK;
}
public static HRESULT InitPropVariantFromGUIDAsBuffer(Guid guid, PROPVARIANT* ppropvar)
{
return Windows2.InitPropVariantFromBuffer(&guid, (uint)sizeof(Guid), ppropvar);
}
public static HRESULT InitPropVariantFromInt16(short nVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_I2;
ppropvar->iVal = nVal;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromInt16Vector(
short* prgn,
uint cElems,
PROPVARIANT* ppropvar);
public static HRESULT InitPropVariantFromInt32(int lVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_I4;
ppropvar->lVal = lVal;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromInt32Vector(
int* prgn,
uint cElems,
PROPVARIANT* ppropvar);
public static HRESULT InitPropVariantFromInt64(long llVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_I8;
ppropvar->hVal.QuadPart = llVal;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromInt64Vector(
long* prgn,
uint cElems,
PROPVARIANT* ppropvar);
public static HRESULT InitPropVariantFromString(ushort* psz, PROPVARIANT* ppropvar)
{
HRESULT hr = (psz != null) ? S_OK : E_INVALIDARG;
if (hr.SUCCEEDED)
{
nuint byteCount = ((nuint)WindowsUtil.GetStringLength((char*)psz) + 1) * sizeof(ushort);
ppropvar->pwszVal = (ushort*)CoTaskMemAlloc(byteCount);
hr = (ppropvar->pwszVal != null) ? S_OK : E_OUTOFMEMORY;
if (hr.SUCCEEDED)
{
BufferUtil.Copy(ppropvar->pwszVal, psz, byteCount);
ppropvar->vt = (ushort)VT_LPWSTR;
}
}
if (hr.FAILED)
{
PropVariantInit(ppropvar);
}
return hr;
}
public static HRESULT InitPropVariantFromUInt16(ushort uiVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_UI2;
ppropvar->uiVal = uiVal;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromUInt16Vector(
ushort* prgn,
uint cElems,
PROPVARIANT* ppropvar);
public static HRESULT InitPropVariantFromUInt32(uint ulVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_UI4;
ppropvar->ulVal = ulVal;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromUInt32Vector(
uint* prgn,
uint cElems,
PROPVARIANT* ppropvar);
public static HRESULT InitPropVariantFromUInt64(ulong ullVal, PROPVARIANT* ppropvar)
{
if (ppropvar == null)
{
return E_POINTER;
}
ppropvar->vt = (ushort)VT_UI8;
ppropvar->uhVal.QuadPart = ullVal;
return S_OK;
}
[DllImport("propsys", ExactSpelling = true)]
public static extern HRESULT InitPropVariantFromUInt64Vector(
ulong* prgn,
uint cElems,
PROPVARIANT* ppropvar);
public static void PropVariantInit(PROPVARIANT* pvar)
{
BufferUtil.Fill(pvar, 0, sizeof(PROPVARIANT));
}
[DllImport("oleaut32", ExactSpelling = true)]
public static extern HRESULT VariantClear(VARIANT* pvarg);
[DllImport("oleaut32", ExactSpelling = true)]
public static extern void VariantInit(VARIANT* pvarg);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment