From c05562e2138edcedd33904abaf14e65889d96000 Mon Sep 17 00:00:00 2001 From: Richard Webb Date: Mon, 26 Aug 2024 21:24:52 +0100 Subject: [PATCH] Rework the handling of FMTID0 in OLEPropertiesContainer --- .../OLEProperties/OLEPropertiesContainer.cs | 68 +++++++++++++++---- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/sources/OpenMcdf.Extensions/OLEProperties/OLEPropertiesContainer.cs b/sources/OpenMcdf.Extensions/OLEProperties/OLEPropertiesContainer.cs index 6ac01193..f973a40c 100644 --- a/sources/OpenMcdf.Extensions/OLEProperties/OLEPropertiesContainer.cs +++ b/sources/OpenMcdf.Extensions/OLEProperties/OLEPropertiesContainer.cs @@ -14,8 +14,15 @@ public class OLEPropertiesContainer public bool HasUserDefinedProperties { get; private set; } - public ContainerType ContainerType { get; internal set; } - private Guid? FmtID0 { get; } + /// + /// Gets the type of the container. + /// + public ContainerType ContainerType { get; } + + /// + /// Gets the FMTID of the properties container. + /// + public Guid FMTID0 { get; } public PropertyContext Context { get; private set; } @@ -68,6 +75,11 @@ public static OLEPropertiesContainer CreateNewSummaryInfo(SummaryInfoProperties return null; } + /// + /// Create a new instance of with the specified code page and container type. + /// + /// The code page to use for the new container. + /// The type of the new container. public OLEPropertiesContainer(int codePage, ContainerType containerType) { Context = new PropertyContext @@ -77,6 +89,7 @@ public OLEPropertiesContainer(int codePage, ContainerType containerType) }; ContainerType = containerType; + FMTID0 = FmtIdFromContainerType(containerType); } internal OLEPropertiesContainer(CFStream cfStream) @@ -86,13 +99,8 @@ internal OLEPropertiesContainer(CFStream cfStream) this.cfStream = cfStream; pStream.Read(new BinaryReader(new StreamDecorator(cfStream))); - ContainerType = pStream.FMTID0.ToString("B").ToUpperInvariant() switch - { - WellKnownFMTID.FMTID_SummaryInformation => ContainerType.SummaryInfo, - WellKnownFMTID.FMTID_DocSummaryInformation => ContainerType.DocumentSummaryInfo, - _ => ContainerType.AppSpecific, - }; - FmtID0 = pStream.FMTID0; + FMTID0 = pStream.FMTID0; + ContainerType = ContainerTypeFromFmtId(pStream.FMTID0); PropertyNames = (Dictionary)pStream.PropertySet0.Properties .Where(p => p.PropertyType == PropertyType.DictionaryProperty).FirstOrDefault()?.Value; @@ -126,8 +134,6 @@ internal OLEPropertiesContainer(CFStream cfStream) UserDefinedProperties = new OLEPropertiesContainer(pStream.PropertySet1.PropertyContext.CodePage, ContainerType.UserDefinedProperties); HasUserDefinedProperties = true; - UserDefinedProperties.ContainerType = ContainerType.UserDefinedProperties; - for (int i = 0; i < pStream.PropertySet1.Properties.Count; i++) { if (pStream.PropertySet1.PropertyIdentifierAndOffsets[i].PropertyIdentifier == 0) continue; @@ -227,8 +233,6 @@ public void Save(CFStream cfStream) Stream s = new StreamDecorator(cfStream); BinaryWriter bw = new BinaryWriter(s); - Guid fmtId0 = FmtID0 ?? (ContainerType == ContainerType.SummaryInfo ? new Guid(WellKnownFMTID.FMTID_SummaryInformation) : new Guid(WellKnownFMTID.FMTID_DocSummaryInformation)); - PropertySetStream ps = new PropertySetStream { ByteOrder = 0xFFFE, @@ -238,7 +242,7 @@ public void Save(CFStream cfStream) NumPropertySets = 1, - FMTID0 = fmtId0, + FMTID0 = this.FMTID0, Offset0 = 0, FMTID1 = Guid.Empty, @@ -312,5 +316,41 @@ private void AddDictionaryPropertyToPropertySet(Dictionary propert propertySet.Properties.Add(dictionaryProperty); propertySet.PropertyIdentifierAndOffsets.Add(new PropertyIdentifierAndOffset() { PropertyIdentifier = 0, Offset = 0 }); } + + // Determine the type of the container from the FMTID0 property. + private static ContainerType ContainerTypeFromFmtId(Guid fmtId0) + { + if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_SummaryInformation)) + return ContainerType.SummaryInfo; + else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_DocSummaryInformation)) + return ContainerType.DocumentSummaryInfo; + else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_GlobalInfo)) + return ContainerType.GlobalInfo; + else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_ImageInfo)) + return ContainerType.ImageInfo; + else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_ImageContents)) + return ContainerType.ImageContents; + + return ContainerType.AppSpecific; + } + + // Determine the FMTID property from the container type. + // Note: Uses FMTID_DocSummaryInformation by default to match the previous behavior. + private static Guid FmtIdFromContainerType(ContainerType containerType) + { + switch (containerType) + { + case ContainerType.SummaryInfo: + return Guid.Parse(WellKnownFMTID.FMTID_SummaryInformation); + case ContainerType.GlobalInfo: + return Guid.Parse(WellKnownFMTID.FMTID_GlobalInfo); + case ContainerType.ImageContents: + return Guid.Parse(WellKnownFMTID.FMTID_ImageContents); + case ContainerType.ImageInfo: + return Guid.Parse(WellKnownFMTID.FMTID_ImageInfo); + default: + return Guid.Parse(WellKnownFMTID.FMTID_DocSummaryInformation); + } + } } }