Compartir a través de


Almacenamiento estructurado en MAPI

Hace referencia a: Outlook 2013 | Outlook 2016

El almacenamiento estructurado hace referencia a la organización jerárquica del almacenamiento introducida con COM. En un entorno de almacenamiento estructurado, el almacenamiento se organiza en dos o tres tipos de objetos:

  • Stream objetos

  • Bloquear objetos bytes

  • Objetos de almacenamiento

Stream y los bytes de bloqueo son objetos de nivel inferior que acceden directamente a los datos. Stream objetos implementan la interfaz IStream que define métodos para leer, escribir, colocar y copiar bytes de datos. Los objetos de bytes de bloqueo implementan otra interfaz COM, ILockBytes, para acceder a los datos con una matriz de bytes. Las matrices de bytes se usan normalmente para proporcionar acceso personalizado al almacenamiento subyacente.

Los objetos de almacenamiento se superponen sobre los objetos stream o lock bytes; pueden contener uno o varios de estos objetos, así como otros objetos de almacenamiento. Los objetos de almacenamiento implementan la interfaz IStorage que define métodos para crear, acceder y mantener objetos anidados.

Dado que IStream, ILockBytes e IStorage son interfaces COM en lugar de interfaces MAPI, sus métodos devuelven valores de error COM en lugar de valores MAPI. Los clientes y proveedores de servicios que llaman a métodos en estas interfaces deben usar la función de API MapStorageSCode para traducir estos valores en valores de error MAPI. Para obtener más información, vea MapStorageSCode.

Los clientes y proveedores de servicios usan almacenamiento estructurado para trabajar con propiedades demasiado grandes para mantener con los métodos IMAPIProp , normalmente grandes cadenas y propiedades binarias. Una de las maneras comunes en que los clientes o proveedores de servicios acceden a ellos es especificando IStream o IStorage como identificador de interfaz en una llamada al método IMAPIProp::OpenProperty . Por ejemplo, los clientes llaman a OpenProperty con PR_ATTACH_DATA_BIN como la etiqueta de propiedad y IID_IStream como identificador de interfaz para acceder a datos adjuntos binarios en un mensaje.

Los clientes y proveedores de servicios pueden implementar sus propios objetos de flujo y almacenamiento o llamar a funciones de API para acceder a las implementaciones proporcionadas por MAPI o COM. Dado que las implementaciones proporcionadas sirven a la mayoría de los propósitos, los clientes y proveedores de servicios rara vez necesitan crear sus propios.

Cuando un cliente llama a OpenProperty en un objeto MAPI para acceder a una de sus propiedades a través de un objeto de almacenamiento, el proveedor de servicios normalmente abrirá el objeto de almacenamiento en modo directo. Sin embargo, esto es típico en lugar de un comportamiento necesario. Los clientes deben suponer que todos los objetos de almacenamiento abiertos o creados por los proveedores de servicios se realizan transacciones y requieren una llamada a IStorage::Commit. También deben recordar que los cambios en los objetos de almacenamiento no se harán permanentes hasta que llamen a IMAPIProp::SaveChanges después de la confirmación final para guardar el objeto MAPI. Para obtener más información, vea IMAPIProp::SaveChanges.

MAPI y COM proporcionan varias funciones de API para definir o acceder a objetos de almacenamiento y secuencia. Las funciones usadas habitualmente se describen en la tabla siguiente.

Funciones para acceder a objetos de almacenamiento y Stream

Función Descripción
HrIStorageFromStream
Crea un objeto de almacenamiento para acceder a un objeto de secuencia o bytes de bloqueo.
OpenIMsgOnIStg
Crea un objeto de mensaje para acceder a un objeto de almacenamiento.
OpenStreamOnFile
Crea un objeto de secuencia para acceder a un archivo.
WrapCompressedRTFStream
Crea un objeto de secuencia que contiene la versión comprimida o sin comprimir de una secuencia que contiene el texto enriquecido de un mensaje.

Para recuperar los nombres de las secuencias en un subalmacenamiento determinado

  1. Llame al método IStorage::EnumElements del substorage para obtener una interfaz IEnumSTATSTG .

  2. Llame a IEnumSTATSTG::Next con tantas estructuras STATSTG a la vez como pueda. Si solicita 100 a la vez, Next normalmente devolverá S_FALSE con el contenido de pceltFetched establecido en el número que se recuperó realmente.

  3. Compruebe las estructuras STATSTG marcadas con STGTY_STREAM.

  4. Libere el parámetro pwcsName .

Para crear un objeto de almacenamiento para acceder a un objeto de secuencia o bytes de bloqueo existente

Para crear un objeto de mensaje para acceder a un objeto de almacenamiento existente

  • Los proveedores de servicios y los clientes llaman a OpenIMsgOnIStg. El objeto de mensaje que se crea difiere de los objetos de mensaje que suelen crear los proveedores de almacén de mensajes en que no admite todos los métodos de interfaz IMessage : IMAPIProp , como IMessage::SubmitMessage. Un parámetro de entrada opcional para OpenIMsgOnIStg es una función de devolución de llamada que se ajusta al prototipo MSGCALLRELEASE . El nuevo objeto de mensaje llama a esta función cuando el recuento de referencias del mensaje alcanza cero. La implementación de una función MSGCALLRELEASE puede ser útil para realizar el procesamiento final antes de que el nuevo mensaje se quite por completo.

OpenStreamOnFile se usa normalmente para almacenar datos adjuntos de archivos porque crea una secuencia que lee y escribe en un archivo. OpenProperty con PR_ATTACH_DATA_BIN como la etiqueta de propiedad crea una secuencia para almacenar datos adjuntos binarios.

Para comprimir o descomprimir una secuencia que contiene texto del mensaje en formato de texto enriquecido

  • Los clientes llaman a WrapCompressedRTFStream. WrapCompressedRTFStream crea una secuencia que encapsula la secuencia RTF. El flujo contenedor no implementa todos los métodos IStream ; Se excluyen los métodos siguientes: Seek, SetSize, Revert, LockRegion, UnlockRegion, Stat y Clone. Esto se debe a que los objetos de secuencia creados por WrapCompressedRTFStream no admiten SetSize o Stat, no hay una manera sencilla de ampliar o recuperar su tamaño. La mejor estrategia es elegir un tamaño de búfer razonable y leer o escribir en un bucle.

Nota:

COM tiene una implementación de objeto de almacenamiento basada en una matriz de bytes que devuelve un objeto IEnumSTATSTG del método EnumElements que es problemático. En concreto, el método QueryInterface no funciona correctamente. Los proveedores de servicios que implementan sus propios objetos de almacenamiento mediante la implementación COM deben crear un contenedor fino para el objeto IEnumSTATSTG que reenvía llamadas a los métodos IEnumSTATSTG subyacentes, pero implementa sus propios métodos AddRef, Release, QueryInterface y Clone .