public NativeMethods.IStorage GetStorage(string Path) { if (STGRefs.ContainsKey(Path.ToUpper())) { return(STGRefs[Path.ToUpper()]); } NativeMethods.IStorage newStorage; string[] chunks = Path.Split('\\'); string name = chunks.Last(); string parentPath = Path.Replace("\\" + name, ""); NativeMethods.IStorage parentStorage = GetStorage(parentPath); parentStorage.OpenStorage(name, null, NativeMethods.STGM.READWRITE | NativeMethods.STGM.SHARE_EXCLUSIVE, IntPtr.Zero, 0, out newStorage); STGRefs[Path.ToUpper()] = newStorage; return(newStorage); }
/// <summary> /// Gets the MAPI property value from a stream or storage in this storage. /// </summary> /// <param name="propIdentifier"> The 4 char hexadecimal prop identifier. </param> /// <returns> The value of the MAPI property or null if not found. </returns> private object GetMapiPropertyFromStreamOrStorage(string propIdentifier) { // Get list of stream and storage identifiers which map to properties var propKeys = new List <string>(); propKeys.AddRange(_streamStatistics.Keys); propKeys.AddRange(_subStorageStatistics.Keys); // Determine if the property identifier is in a stream or sub storage string propTag = null; var propType = PropertyType.PT_UNSPECIFIED; foreach (var propKey in propKeys) { if (!propKey.StartsWith(MapiTags.SubStgVersion1 + "_" + propIdentifier)) { continue; } propTag = propKey.Substring(12, 8); propType = (PropertyType)ushort.Parse(propKey.Substring(16, 4), NumberStyles.HexNumber); break; } // When null then we didn't find the property if (propTag == null) { return(null); } // Depending on prop type use method to get property value var containerName = MapiTags.SubStgVersion1 + "_" + propTag; switch (propType) { case PropertyType.PT_UNSPECIFIED: return(null); case PropertyType.PT_STRING8: //return GetStreamAsString(containerName, Encoding.UTF8); return(GetStreamAsString(containerName, Encoding.Default)); case PropertyType.PT_UNICODE: return(GetStreamAsString(containerName, Encoding.Unicode)); case PropertyType.PT_BINARY: return(GetStreamBytes(containerName)); case PropertyType.PT_MV_STRING8: case PropertyType.PT_MV_UNICODE: // If the property is a unicode multiview item we need to read all the properties // again and filter out all the multivalue names, they end with -00000000, -00000001, etc.. var multiValueContainerNames = propKeys.Where(propKey => propKey.StartsWith(containerName + "-")).ToList(); var values = new List <string>(); foreach (var multiValueContainerName in multiValueContainerNames) { var value = GetStreamAsString(multiValueContainerName, propType == PropertyType.PT_MV_STRING8 ? Encoding.Default : Encoding.Unicode); // Multi values always end with a null char so we need to strip that one off if (value.EndsWith("/0")) { value = value.Substring(0, value.Length - 1); } values.Add(value); } return(values); case PropertyType.PT_OBJECT: return (NativeMethods.CloneStorage( _storage.OpenStorage(containerName, IntPtr.Zero, NativeMethods.STGM.READ | NativeMethods.STGM.SHARE_EXCLUSIVE, IntPtr.Zero, 0), true)); default: throw new ApplicationException("MAPI property has an unsupported type and can not be retrieved."); } }