public static bool TryGetMetadataByName(this IWICMetadataQueryReader meta, string name, out PropVariant value)
        {
            value = null;

            int hr = ProxyFunctions.GetMetadataByName(meta, name, IntPtr.Zero);

            if (hr >= 0)
            {
                value = new PropVariant();

                var pvMarshal = new PropVariant.Marshaler();
                var pvNative  = pvMarshal.MarshalManagedToNative(value);
                hr = ProxyFunctions.GetMetadataByName(meta, name, pvNative);
                pvMarshal.MarshalNativeToManaged(pvNative);
                pvMarshal.CleanUpNativeData(pvNative);
            }

            return(hr >= 0);
        }
예제 #2
0
            public IntPtr MarshalManagedToNative(object o)
            {
                if (o == null)
                {
                    return(IntPtr.Zero);
                }

                var marshalType = PropVariantMarshalType.Automatic;

                if (o is PropVariant)
                {
                    pv          = (PropVariant)o;
                    o           = pv.Value;
                    marshalType = pv.MarshalType;
                }

                var pNativeData = allocatePropVariant();

                if (o == null)
                {
                    return(pNativeData);
                }

                var type = o.GetType();

                if (!(o is Array))
                {
                    if (marshalType == PropVariantMarshalType.Ascii)
                    {
                        var upv = new UnmanagedPropVariant();
                        upv.vt           = (ushort)VarEnum.VT_LPSTR;
                        upv.pointerValue = Marshal.StringToCoTaskMemAnsi((string)o);
                        Marshal.StructureToPtr(upv, pNativeData, false);
                    }
                    else if (o is string)
                    {
                        var upv = new UnmanagedPropVariant();
                        upv.vt           = (ushort)VarEnum.VT_LPWSTR;
                        upv.pointerValue = Marshal.StringToCoTaskMemUni((string)o);
                        Marshal.StructureToPtr(upv, pNativeData, false);
                    }
                    else if (o is DateTime)
                    {
                        var upv = new UnmanagedPropVariant();
                        upv.vt         = (ushort)VarEnum.VT_FILETIME;
                        upv.int64Value = ((DateTime)o).ToFileTimeUtc();
                        Marshal.StructureToPtr(upv, pNativeData, false);
                    }
                    else
                    {
                        Marshal.GetNativeVariantForObject(o, pNativeData);
                    }
                }
                else if ((type.Equals(typeof(byte []))) || (type.Equals(typeof(sbyte []))) ||
                         (type.Equals(typeof(short[]))) || (type.Equals(typeof(ushort[]))) ||
                         (type.Equals(typeof(int  []))) || (type.Equals(typeof(uint  []))) ||
                         (type.Equals(typeof(long []))) || (type.Equals(typeof(ulong []))) ||
                         (type.Equals(typeof(float[]))) || (type.Equals(typeof(double[]))))
                {
                    var a             = (Array)o;
                    int count         = a.Length;
                    int elementSize   = Marshal.SizeOf(type.GetElementType());
                    var pNativeBuffer = Marshal.AllocCoTaskMem(elementSize * count);

                    var gch = GCHandle.Alloc(a, GCHandleType.Pinned);
                    for (int i = 0; i < count; i++)
                    {
                        var pNativeValue = Marshal.UnsafeAddrOfPinnedArrayElement(a, i);
                        for (int j = 0; j < elementSize; j++)
                        {
                            byte value = Marshal.ReadByte(pNativeValue, j);
                            Marshal.WriteByte(pNativeBuffer, elementSize * i + j, value);
                        }
                    }
                    gch.Free();

                    var upv = new UnmanagedPropVariant();
                    upv.vectorValue.count = (uint)count;
                    upv.vectorValue.ptr   = pNativeBuffer;
                    upv.vt = (ushort)(pv ?? new PropVariant(o)).UnmanagedType;

                    Marshal.StructureToPtr(upv, pNativeData, false);
                }
                else if (type.Equals(typeof(string[])))
                {
                    int count         = ((Array)o).Length;
                    var pNativeBuffer = Marshal.AllocCoTaskMem(IntPtr.Size * count);

                    for (int i = 0; i < count; i++)
                    {
                        var strPtr = Marshal.StringToCoTaskMemUni(((string[])o)[i]);
                        Marshal.WriteIntPtr(pNativeBuffer, IntPtr.Size * i, strPtr);
                    }

                    var upv = new UnmanagedPropVariant();
                    upv.vectorValue.count = (uint)count;
                    upv.vectorValue.ptr   = pNativeBuffer;
                    upv.vt = (ushort)(pv ?? new PropVariant(o)).UnmanagedType;

                    Marshal.StructureToPtr(upv, pNativeData, false);
                }
                else
                {
                    throw new NotImplementedException();
                }

                return(pNativeData);
            }
        public static bool TrySetMetadataByName(this IWICMetadataQueryWriter meta, string name, PropVariant value)
        {
            var pvMarshal = new PropVariant.Marshaler();
            var pvNative  = pvMarshal.MarshalManagedToNative(value);
            int hr        = ProxyFunctions.SetMetadataByName(meta, name, pvNative);

            pvMarshal.CleanUpNativeData(pvNative);

            return(hr >= 0);
        }