/// <summary>
        /// Initializes a new instance of the <see cref="CompoundProperty"/> class.
        /// </summary>
        /// <param name="formatId">The format id.</param>
        /// <param name="name">The name.</param>
        public CompoundProperty(Guid formatId, string name)
        {
            // determine id
            CompoundProperty kp = null;

            foreach (var property in KnownProperties)
            {
                if (property.FormatId == formatId &&
                    string.Compare(name, property.Name, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    kp = property;
                    break;
                }
            }

            if (kp != null)
            {
                FormatId = kp.FormatId;
                Name     = kp.Name;
                Id       = kp.Id;
            }
            else
            {
                FormatId = formatId;
                Name     = name;
            }
            Changed = true;
        }
示例#2
0
        private static PROPSPEC GetPROPSEC(CompoundProperty prop)
        {
            var spec = new PROPSPEC();

            if (prop.IsKnownProperty)
            {
                spec.ulKind       = PRSPEC.PRSPEC_PROPID;
                spec.union.propid = prop.Id;
            }
            else
            {
                spec.ulKind       = PRSPEC.PRSPEC_LPWSTR;
                spec.union.lpwstr = Marshal.StringToCoTaskMemUni(prop.Name);
            }
            return(spec);
        }
示例#3
0
        private static PROPVARIANT GetPROPVARIANT(CompoundProperty prop)
        {
            var var = new PROPVARIANT();

            if (prop.Value == null)
            {
                return(var);
            }

            var code = Type.GetTypeCode(prop.Value.GetType());

            switch (code)
            {
            case TypeCode.Boolean:
                var.vt            = VARTYPE.VT_BOOL;
                var.union.boolVal = (bool)prop.Value ? (short)1 : (short)0;
                break;

            case TypeCode.Byte:
                var.vt         = VARTYPE.VT_UI1;
                var.union.bVal = (byte)prop.Value;
                break;

            case TypeCode.Char:
                var.vt           = VARTYPE.VT_LPSTR;
                var.union.pszVal = Marshal.StringToCoTaskMemAnsi(((char)prop.Value).ToString(CultureInfo.InvariantCulture));
                break;

            case TypeCode.DateTime:
                var.vt             = VARTYPE.VT_FILETIME;
                var.union.filetime = ((DateTime)prop.Value).ToFileTime();
                break;

            case TypeCode.Decimal:
                var dec = IntPtr.Zero;
                Marshal.StructureToPtr((decimal)prop.Value, dec, fDeleteOld: false);
                var    = (PROPVARIANT)Marshal.PtrToStructure(dec, typeof(PROPVARIANT));
                var.vt = VARTYPE.VT_DECIMAL;
                break;

            case TypeCode.Double:
                var.vt           = VARTYPE.VT_R8;
                var.union.dblVal = (double)prop.Value;
                break;

            case TypeCode.Int16:
                var.vt         = VARTYPE.VT_I2;
                var.union.iVal = (short)prop.Value;
                break;

            case TypeCode.Int32:
                var.vt         = VARTYPE.VT_I4;
                var.union.lVal = (int)prop.Value;
                break;

            case TypeCode.Int64:
                var.vt         = VARTYPE.VT_I8;
                var.union.hVal = (long)prop.Value;
                break;

            case TypeCode.SByte:
                var.vt         = VARTYPE.VT_I1;
                var.union.cVal = (sbyte)prop.Value;
                break;

            case TypeCode.Single:
                var.vt           = VARTYPE.VT_R4;
                var.union.fltVal = (float)prop.Value;
                break;

            case TypeCode.String:
                var.vt           = VARTYPE.VT_LPSTR;
                var.union.pszVal = Marshal.StringToCoTaskMemAnsi((string)prop.Value);
                break;

            case TypeCode.UInt16:
                var.vt          = VARTYPE.VT_UI2;
                var.union.uiVal = (ushort)prop.Value;
                break;

            case TypeCode.UInt32:
                var.vt          = VARTYPE.VT_UI4;
                var.union.ulVal = (uint)prop.Value;
                break;

            case TypeCode.UInt64:
                var.vt          = VARTYPE.VT_UI8;
                var.union.uhVal = (ulong)prop.Value;
                break;

            case TypeCode.Object:
                if (prop.Value is Guid)
                {
                    var.vt           = VARTYPE.VT_LPSTR;
                    var.union.pszVal = Marshal.StringToCoTaskMemAnsi(((Guid)prop.Value).ToString());
                }
                break;
            }
            return(var);
        }
示例#4
0
        private void LoadPropertySet(IPropertySetStorage propertySetStorage, Guid fmtid)
        {
            var guid = fmtid;
            var hr   = propertySetStorage.Open(ref guid, STGM.STGM_READ | STGM.STGM_SHARE_EXCLUSIVE, out var propertyStorage);

            if (hr == STG_E_FILENOTFOUND || hr == STG_E_ACCESSDENIED)
            {
                return;
            }

            if (hr != 0)
            {
                throw new Win32Exception((int)hr);
            }

            propertyStorage.Enum(out var es);
            if (es == null)
            {
                return;
            }

            try
            {
                var stg = new STATPROPSTG();
                int fetched;
                do
                {
                    hr = es.Next(1, ref stg, out fetched);
                    if (hr != 0 && hr != 1)
                    {
                        throw new Win32Exception((int)hr);
                    }

                    if (fetched == 1)
                    {
                        var name = GetPropertyName(fmtid, propertyStorage, stg);

                        var propsec = new PROPSPEC[]
                        {
                            new PROPSPEC
                            {
                                ulKind = stg.lpwstrName != null ? PRSPEC.PRSPEC_LPWSTR : PRSPEC.PRSPEC_PROPID,
                            },
                        };

                        var lpwstr = IntPtr.Zero;
                        if (stg.lpwstrName != null)
                        {
                            lpwstr = Marshal.StringToCoTaskMemUni(stg.lpwstrName);
                            propsec[0].union.lpwstr = lpwstr;
                        }
                        else
                        {
                            propsec[0].union.propid = stg.propid;
                        }

                        var vars = new PROPVARIANT[1];
                        vars[0] = new PROPVARIANT();
                        try
                        {
                            hr = propertyStorage.ReadMultiple(1, propsec, vars);
                            if (hr != 0)
                            {
                                throw new Win32Exception((int)hr);
                            }
                        }
                        finally
                        {
                            if (lpwstr != IntPtr.Zero)
                            {
                                Marshal.FreeCoTaskMem(lpwstr);
                            }
                        }

                        object value;
                        try
                        {
                            switch (vars[0].vt)
                            {
                            case VARTYPE.VT_BOOL:
                                value = vars[0].union.boolVal != 0 ? true : false;
                                break;

                            case VARTYPE.VT_BSTR:
                                value = Marshal.PtrToStringUni(vars[0].union.bstrVal);
                                break;

                            case VARTYPE.VT_CY:
                                value = decimal.FromOACurrency(vars[0].union.cyVal);
                                break;

                            case VARTYPE.VT_DATE:
                                value = DateTime.FromOADate(vars[0].union.date);
                                break;

                            case VARTYPE.VT_DECIMAL:
                                var dec = IntPtr.Zero;
                                Marshal.StructureToPtr(vars[0], dec, false);
                                value = Marshal.PtrToStructure(dec, typeof(decimal));
                                break;

                            case VARTYPE.VT_DISPATCH:
                                value = Marshal.GetObjectForIUnknown(vars[0].union.pdispVal);
                                break;

                            case VARTYPE.VT_ERROR:
                            case VARTYPE.VT_HRESULT:
                                value = vars[0].union.scode;
                                break;

                            case VARTYPE.VT_FILETIME:
                                value = DateTime.FromFileTime(vars[0].union.filetime);
                                break;

                            case VARTYPE.VT_I1:
                                value = vars[0].union.cVal;
                                break;

                            case VARTYPE.VT_I2:
                                value = vars[0].union.iVal;
                                break;

                            case VARTYPE.VT_I4:
                                value = vars[0].union.lVal;
                                break;

                            case VARTYPE.VT_I8:
                                value = vars[0].union.hVal;
                                break;

                            case VARTYPE.VT_INT:
                                value = vars[0].union.intVal;
                                break;

                            case VARTYPE.VT_LPSTR:
                                value = Marshal.PtrToStringAnsi(vars[0].union.pszVal);
                                break;

                            case VARTYPE.VT_LPWSTR:
                                value = Marshal.PtrToStringUni(vars[0].union.pwszVal);
                                break;

                            case VARTYPE.VT_R4:
                                value = vars[0].union.fltVal;
                                break;

                            case VARTYPE.VT_R8:
                                value = vars[0].union.dblVal;
                                break;

                            case VARTYPE.VT_UI1:
                                value = vars[0].union.bVal;
                                break;

                            case VARTYPE.VT_UI2:
                                value = vars[0].union.uiVal;
                                break;

                            case VARTYPE.VT_UI4:
                                value = vars[0].union.ulVal;
                                break;

                            case VARTYPE.VT_UI8:
                                value = vars[0].union.uhVal;
                                break;

                            case VARTYPE.VT_UINT:
                                value = vars[0].union.uintVal;
                                break;

                            case VARTYPE.VT_UNKNOWN:
                                value = Marshal.GetObjectForIUnknown(vars[0].union.punkVal);
                                break;

                            default:
                                value = null;
                                break;
                            }
                        }
                        finally
                        {
                            PropVariantClear(ref vars[0]);
                        }

                        var property = new CompoundProperty(fmtid, name, stg.propid)
                        {
                            Value   = value,
                            Changed = false,
                        };
                        Properties.InternalAdd(property);
                    }
                }while (fetched == 1);
            }
            finally
            {
                Marshal.ReleaseComObject(es);
            }
        }