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); }
private static string GetPropertyValue(IWiaPropertyStorage propertyStorage, uint propid) { PROPVARIANT[] propvars = new PROPVARIANT[1]; PROPSPEC[] propspec = new PROPSPEC[1]; propspec[0].ulKind = (uint)1;//PRSPEC.PROPID; propspec[0].u.propId = propid; try { if (Success(propertyStorage.ReadMultiple(1, propspec, propvars))) { return(propvars[0].Value.ToString()); } } finally { propvars[0].Clear(); } return(null); }
/// <summary> /// Commits the changes if any. /// </summary> /// <returns>true if changes were detected and commited; otherwise false.</returns> public bool CommitChanges() { // group properties by property set (fmtid) var sets = new Dictionary <Guid, List <CompoundProperty> >(); foreach (var property in TouchedProperties) { if (!sets.TryGetValue(property.FormatId, out var list)) { list = new List <CompoundProperty>(); sets.Add(property.FormatId, list); } list.Add(property); } if (sets.Count == 0) { return(false); } var mode = GetMode(readOnly: false); var guid = typeof(IPropertySetStorage).GUID; var hr = StgOpenStorageEx(FilePath, mode, STGFMT.STGFMT_ANY, 0, IntPtr.Zero, IntPtr.Zero, ref guid, out var propertySetStorage); if (hr == STG_E_FILENOTFOUND || hr == STG_E_PATHNOTFOUND) { throw new FileNotFoundException(null, FilePath); } if (hr != 0) { throw new Win32Exception((int)hr); } try { foreach (var kvp in sets) { var fmtid = kvp.Key; const STGM Mode2 = STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE; hr = propertySetStorage.Open(ref fmtid, Mode2, out var propertyStorage); if (hr == STG_E_FILENOTFOUND) { if (OnlyDeletes(kvp.Value)) { continue; } var nullGuid = Guid.Empty; hr = propertySetStorage.Create(ref fmtid, ref nullGuid, PROPSETFLAG_ANSI, Mode2, out propertyStorage); } if (hr != 0) { throw new Win32Exception((int)hr); } try { foreach (var property in kvp.Value) { if (property.Deleted) { var specs = new PROPSPEC[] { GetPROPSEC(property), }; try { hr = propertyStorage.DeleteMultiple(1, specs); if (hr != 0) { throw new Win32Exception((int)hr); } } finally { FreePROPSEC(ref specs[0]); } } } foreach (var property in kvp.Value) { if (property.Changed) { var specs = new PROPSPEC[] { GetPROPSEC(property), }; var vars = new PROPVARIANT[] { GetPROPVARIANT(property), }; try { hr = propertyStorage.WriteMultiple(1, specs, vars, USERDEFINEDPROPERTIES_MIN); if (hr != 0) { throw new Win32Exception((int)hr); } } finally { FreePROPSEC(ref specs[0]); PropVariantClear(ref vars[0]); } } } propertyStorage.Commit(0); } finally { Marshal.ReleaseComObject(propertyStorage); } } } finally { if (propertySetStorage != null) { Marshal.ReleaseComObject(propertySetStorage); } } Properties.Commit(); return(true); }
private static void FreePROPSEC(ref PROPSPEC spec) { Marshal.FreeCoTaskMem(spec.union.lpwstr); spec.union.lpwstr = IntPtr.Zero; }
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); } }
void IPropertyStorage.DeleteMultiple( UInt32 cpspec, PROPSPEC[] rgpspec ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.DeleteMultiple( cpspec, rgpspec ); }
void IPropertyStorage.WriteMultiple( UInt32 cpspec, PROPSPEC[] rgpspec, PROPVARIANT[] rgpropvar, uint propidNameFirst ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.WriteMultiple( cpspec, rgpspec, rgpropvar, propidNameFirst ); }
// // We preserve the HRESULT on this method because we need to distinguish // between S_OK (we got the properties we asked for) and S_FALSE (none of // the properties exist). // int IPropertyStorage.ReadMultiple( UInt32 cpspec, PROPSPEC[] rgpspec, PROPVARIANT[] rgpropvar ) { SecurityHelper.DemandCompoundFileIOPermission(); return _unsafePropertyStorage.ReadMultiple( cpspec, rgpspec, rgpropvar ); }
private static DocumentPropertyCollection ReadFromStructuredStorage(string path) { var result = NativeMethods.StgOpenStorage(path, null, STGM.READ | STGM.SHARE_DENY_WRITE, IntPtr.Zero, 0, out var storage); if (result != 0) { var e = Marshal.GetExceptionForHR(result); throw e; } var propertySetStorage = storage as IPropertySetStorage; var properties = new DocumentPropertyCollection(); foreach (var statPropSetStg in propertySetStorage.AsEnumerable()) { var fmtid = statPropSetStg.fmtid; propertySetStorage.Open(ref fmtid, (uint)(STGM.READ | STGM.SHARE_EXCLUSIVE), out var propertyStorage); foreach (var statPropStg in propertyStorage.AsEnumerable()) { var propSpecArray = new PROPSPEC[1]; const uint PRSPEC_PROPID = 1; propSpecArray[0].ulKind = PRSPEC_PROPID; propSpecArray[0].unionmember = new IntPtr(statPropStg.PROPID); var propVariantArray = new PropVariant[1]; propertyStorage.ReadMultiple(1, propSpecArray, propVariantArray); var propVariant = propVariantArray[0]; try { var value = propVariant.Value; DocumentPropertyId id; if (statPropSetStg.fmtid == PropertySetId.Summary) { switch ((StgSummaryPropertyId)statPropStg.PROPID) { case StgSummaryPropertyId.Author: id = DocumentPropertyId.Creator; break; case StgSummaryPropertyId.CharCount: id = DocumentPropertyId.Characters; break; case StgSummaryPropertyId.Comments: id = DocumentPropertyId.Description; break; case StgSummaryPropertyId.CreateDate: id = DocumentPropertyId.Created; break; case StgSummaryPropertyId.CreatingApplicationName: id = DocumentPropertyId.Application; break; case StgSummaryPropertyId.Keywords: id = DocumentPropertyId.Keywords; break; case StgSummaryPropertyId.LastAuthor: id = DocumentPropertyId.LastModifiedBy; break; case StgSummaryPropertyId.LastPrinted: id = DocumentPropertyId.LastPrinted; break; case StgSummaryPropertyId.LastSaveDate: id = DocumentPropertyId.Modified; break; case StgSummaryPropertyId.PageCount: id = DocumentPropertyId.Pages; break; case StgSummaryPropertyId.RevisionNumber: id = DocumentPropertyId.Revision; break; case StgSummaryPropertyId.Security: id = DocumentPropertyId.DocSecurity; break; case StgSummaryPropertyId.Subject: id = DocumentPropertyId.Subject; break; case StgSummaryPropertyId.Template: id = DocumentPropertyId.Template; break; case StgSummaryPropertyId.Title: id = DocumentPropertyId.Title; break; case StgSummaryPropertyId.TotalEditingTime: id = DocumentPropertyId.TotalTime; var dateTime = (DateTime)value; var timeSpan = dateTime - DateTime.FromFileTimeUtc(0); value = timeSpan; break; case StgSummaryPropertyId.WordCount: id = DocumentPropertyId.Words; break; default: throw new NotImplementedException(); } } else if (statPropSetStg.fmtid == PropertySetId.DocumentSummary) { id = DocumentPropertyId.None; switch ((StgDocumentSummaryPropertyId)statPropStg.PROPID) { case StgDocumentSummaryPropertyId.ByteCount: break; case StgDocumentSummaryPropertyId.Category: id = DocumentPropertyId.Category; break; case StgDocumentSummaryPropertyId.Company: id = DocumentPropertyId.Company; break; case StgDocumentSummaryPropertyId.HeadingPairs: break; case StgDocumentSummaryPropertyId.HiddenSlideCount: break; case StgDocumentSummaryPropertyId.LineCount: id = DocumentPropertyId.Lines; break; case StgDocumentSummaryPropertyId.LinksUpToDate: id = DocumentPropertyId.LinksUpToDate; break; case StgDocumentSummaryPropertyId.Manager: id = DocumentPropertyId.Manager; break; case StgDocumentSummaryPropertyId.MMClipCount: break; case StgDocumentSummaryPropertyId.NoteCount: break; case StgDocumentSummaryPropertyId.ParagraphCount: id = DocumentPropertyId.Paragraphs; break; case StgDocumentSummaryPropertyId.PresentationTarget: break; case StgDocumentSummaryPropertyId.ScaleCrop: id = DocumentPropertyId.ScaleCrop; break; case StgDocumentSummaryPropertyId.SlideCount: break; case StgDocumentSummaryPropertyId.TitlesofParts: break; default: break; } } else { throw new NotImplementedException(); } if (id != DocumentPropertyId.None) { properties.Add(id, value); } } catch { } } } return(properties); }