/// <summary> /// Processes sub streams and storages on the specified storage. /// </summary> /// <param name="storage"> The storage to get sub streams and storages for. </param> protected virtual void LoadStorage(NativeMethods.IStorage storage) { if (storage == null) { throw new ArgumentNullException("storage", "Storage can not be null"); } _storage = storage; // Ensures memory is released ReferenceManager.AddItem(storage); NativeMethods.IEnumSTATSTG storageElementEnum = null; try { // Enum all elements of the storage storage.EnumElements(0, IntPtr.Zero, 0, out storageElementEnum); // Iterate elements while (true) { // Get 1 element out of the COM enumerator uint elementStatCount; var elementStats = new STATSTG[1]; storageElementEnum.Next(1, elementStats, out elementStatCount); // Break loop if element not retrieved if (elementStatCount != 1) { break; } var elementStat = elementStats[0]; switch (elementStat.type) { case 1: // Element is a storage, add its statistics object to the storage dictionary _subStorageStatistics.Add(elementStat.pwcsName, elementStat); break; case 2: // Element is a stream, add its statistics object to the stream dictionary _streamStatistics.Add(elementStat.pwcsName, elementStat); break; } } } finally { // Free memory if (storageElementEnum != null) { Marshal.ReleaseComObject(storageElementEnum); } } }
internal static IStorage CloneStorage(IStorage source, bool closeSource) { IStorage memoryStorage = null; ILockBytes memoryStorageBytes = null; try { //create a ILockBytes (unmanaged byte array) and then create a IStorage using the byte array as a backing store CreateILockBytesOnHGlobal(IntPtr.Zero, true, out memoryStorageBytes); StgCreateDocfileOnILockBytes(memoryStorageBytes, STGM.CREATE | STGM.READWRITE | STGM.SHARE_EXCLUSIVE, 0, out memoryStorage); //copy the source storage into the new storage source.CopyTo(0, null, IntPtr.Zero, memoryStorage); memoryStorageBytes.Flush(); memoryStorage.Commit(0); // Ensure memory is released ReferenceManager.AddItem(memoryStorage); } catch { if (memoryStorage != null) { Marshal.ReleaseComObject(memoryStorage); } } finally { if (memoryStorageBytes != null) { Marshal.ReleaseComObject(memoryStorageBytes); } if (closeSource) { Marshal.ReleaseComObject(source); } } return(memoryStorage); }