Inicializar un proveedor de almacén de archivos PST ajustado
Hace referencia a: Outlook 2013 | Outlook 2016
Para implementar un proveedor de almacén de archivos de carpetas personales ajustados (PST), debe inicializar el proveedor de almacén PST encapsulado mediante la función MSProviderInit como punto de entrada. Una vez inicializado el archivo DLL del proveedor, la función MSGSERVICEENTRY configura el proveedor de almacén PST encapsulado.
En este tema, la función MSProviderInit y la función MSGSERVICEENTRY se muestran mediante ejemplos de código del proveedor de almacén PST encapsulado de ejemplo. El ejemplo implementa un proveedor de PST encapsulado que está pensado para usarse junto con la API de replicación. Para obtener más información sobre cómo descargar e instalar el proveedor de almacén DE PST encapsulado de ejemplo, vea Instalar el proveedor de almacén PST encapsulado de ejemplo. Para obtener más información sobre la API de replicación, consulte Acerca de la API de replicación.
Después de inicializar un proveedor de almacenamiento PST ajustado, debe implementar funciones para que MAPI y la cola MAPI puedan iniciar sesión en el proveedor del almacén de mensajes. Para obtener más información, vea Iniciar sesión en un proveedor de almacenamiento PST ajustado.
Rutina de inicialización
Todos los proveedores de almacenes PST ajustados deben implementar la función MSProviderInit como punto de entrada para inicializar el archivo DLL del proveedor.
MSProviderInit comprueba si el número de versión de la interfaz del proveedor de servicios, ulMAPIVer
, es compatible con el número de versión actual, CURRENT_SPI_VERSION
. La función guarda las rutinas de administración de memoria MAPI en los g_lpAllocateBuffer
parámetros , g_lpAllocateMore
y g_lpFreeBuffer
. Estas rutinas de administración de memoria deben usarse en toda la implementación del almacén PST encapsulado para la asignación y desasignación de memoria.
Ejemplo de MSProviderInit()
STDINITMETHODIMP MSProviderInit (
HINSTANCE /*hInstance*/,
LPMALLOC lpMalloc,
LPALLOCATEBUFFER lpAllocateBuffer,
LPALLOCATEMORE lpAllocateMore,
LPFREEBUFFER lpFreeBuffer,
ULONG ulFlags,
ULONG ulMAPIVer,
ULONG FAR * lpulProviderVer,
LPMSPROVIDER FAR * lppMSProvider)
{
Log(true,"MSProviderInit function called\n");
if (!lppMSProvider || !lpulProviderVer) return MAPI_E_INVALID_PARAMETER;
HRESULT hRes = S_OK;
*lppMSProvider = NULL;
*lpulProviderVer = CURRENT_SPI_VERSION;
if (ulMAPIVer < CURRENT_SPI_VERSION)
{
Log(true,"MSProviderInit: The version of the subsystem cannot handle this"
+ "version of the provider\n");
return MAPI_E_VERSION;
}
Log(true,"MSProviderInit: saving off memory management routines\n");
g_lpAllocateBuffer = lpAllocateBuffer;
g_lpAllocateMore = lpAllocateMore;
g_lpFreeBuffer = lpFreeBuffer;
HMODULE hm = LoadLibrary("C:\\Program Files\\Common Files\\System" +
"\\MSMAPI\\1033\\MSPST32.dll" );
if (!hm) hm = LoadLibrary("C:\\Program Files\\Microsoft Office\\Office12" +
"\\MSPST32.dll" );
Log(true,"LoadLibrary returned 0x%08X\n", hm);
LPMSPROVIDERINIT pMsProviderInit = NULL;
if (hm)
{
pMsProviderInit = (LPMSPROVIDERINIT)GetProcAddress(hm, "MSProviderInit");
Log(true,"GetProcAddress returned 0x%08X\n", pMsProviderInit);
}
else hRes = E_OUTOFMEMORY;
if (pMsProviderInit)
{
Log(true,"Calling pMsProviderInit\n");
CMSProvider* pWrappedProvider = NULL;
LPMSPROVIDER pSyncProviderObj = NULL;
hRes = pMsProviderInit(
hm,// not hInstance: first param is handle of module in which the function lives
lpMalloc,
lpAllocateBuffer,
lpAllocateMore,
lpFreeBuffer,
ulFlags,
ulMAPIVer,
lpulProviderVer,
&pSyncProviderObj
);
Log(true,"pMsProviderInit returned 0x%08X\n", hRes);
if (SUCCEEDED(hRes))
{
pWrappedProvider = new CMSProvider (pSyncProviderObj);
if (NULL == pWrappedProvider)
{
Log(true,"MSProviderInit: Failed to allocate new CMSProvider object\n");
hRes = E_OUTOFMEMORY;
}
// Copy pointer to the allocated object back into the
//return IMSProvider object pointer
*lppMSProvider = pWrappedProvider;
}
}
else hRes = E_OUTOFMEMORY;
return hRes;
}
Rutas de acceso DE PST y Unicode ajustadas
Para adaptar el ejemplo original preparado en Microsoft Visual Studio 2008 para usar rutas de acceso Unicode al NST para su uso en Microsoft Outlook 2010 habilitadas para Unicode y Outlook 2013, la rutina CreateStoreEntryID, que genera el identificador de entrada, debe usar un formato para las rutas ascii y otro para las rutas de acceso Unicode. Se representan como estructuras en el ejemplo siguiente.
typedef struct // short format
{
BYTE rgbFlags[4]; // MAPI-defined flags
MAPIUID uid; // PST provider MUID
BYTE bReserved; // Reserved (must be zero)
CHAR szPath[1]; // Full path to store (ASCII)
} EIDMS;
// Unicode version of EIDMSW is an extension of EIDMS
// and szPath is always NULL
typedef struct // Long format to support Unicode path and name
{
BYTE rgbFlags[4]; // MAPI-defined flags
MAPIUID uid; // PST provider MUID
BYTE bReserved; // Reserved (must be zero)
CHAR szPath[1]; // ASCII path to store is always NULL
WCHAR wzPath[1]; // Full path to store (Unicode)
} EIDMSW;
Importante
Las diferencias en estas estructuras son dos bytes NULL antes de una ruta de acceso Unicode. Si necesita interpretar el identificador de entrada en la "Rutina de entrada de servicio" que sigue, una manera de determinar si ese es el caso o no sería convertir primero como EIDMS, compruebe si szPath[0] es NULL. Si es así, conversión como EIDMSW en su lugar.
Rutina de entrada de servicio
La función MSGSERVICEENTRY es el punto de entrada del servicio de mensajes donde está configurado el proveedor de almacén PST ajustado. La función llama GetMemAllocRoutines()
a para obtener las rutinas de administración de memoria MAPI. La función usa el lpProviderAdmin
parámetro para buscar la sección de perfil del proveedor y establece las propiedades en el perfil.
Ejemplo de ServiceEntry()
HRESULT STDAPICALLTYPE ServiceEntry (
HINSTANCE /*hInstance*/,
LPMALLOC lpMalloc,
LPMAPISUP lpMAPISup,
ULONG ulUIParam,
ULONG ulFlags,
ULONG ulContext,
ULONG cValues,
LPSPropValue lpProps,
LPPROVIDERADMIN lpProviderAdmin,
LPMAPIERROR FAR *lppMapiError)
{
if (!lpMAPISup || !lpProviderAdmin) return MAPI_E_INVALID_PARAMETER;
HRESULT hRes = S_OK;
Log(true,"ServiceEntry function called\n");
Log(true,"About to call NSTServiceEntry\n");
if (MSG_SERVICE_INSTALL == ulContext ||
MSG_SERVICE_DELETE == ulContext ||
MSG_SERVICE_UNINSTALL == ulContext ||
MSG_SERVICE_PROVIDER_CREATE == ulContext ||
MSG_SERVICE_PROVIDER_DELETE == ulContext)
{
// These contexts are not supported
return MAPI_E_NO_SUPPORT;
}
// Get memory routines
hRes = lpMAPISup->
GetMemAllocRoutines(&g_lpAllocateBuffer,&g_lpAllocateMore,&g_lpFreeBuffer);
HMODULE hm = LoadLibrary("C:\\Program Files\\Common Files\\System" +
"\\MSMAPI\\1033\\MSPST32.dll" );
if (!hm) hm = LoadLibrary("C:\\Program Files\\Microsoft Office\\Office12" +
"\\MSPST32.dll" );
Log(true, "Got module 0x%08X\n", hm);
if (!hm) return E_OUTOFMEMORY;
LPMSGSERVICEENTRY pNSTServiceEntry =
(LPMSGSERVICEENTRY)GetProcAddress(hm, "NSTServiceEntry");
Log(true, "Got procaddress 0x%08X\n", pNSTServiceEntry);
if (!pNSTServiceEntry) return E_OUTOFMEMORY;
// Get profile section
LPPROFSECT lpProfSect = NULL;
hRes = lpProviderAdmin->
OpenProfileSection((LPMAPIUID) NULL, NULL, MAPI_MODIFY, &lpProfSect);
// Set passed in props into the profile
if (lpProps && cValues)
{
hRes = lpProfSect->SetProps(cValues,lpProps,NULL);
}
// Make sure there is a store path set
if (SUCCEEDED(hRes)) hRes = SetOfflineStoreProps(lpProfSect,ulUIParam);
ULONG ulProfProps = 0;
LPSPropValue lpProfProps = NULL;
// Evaluate props
hRes = lpProfSect->GetProps((LPSPropTagArray)&sptClientProps,
fMapiUnicode,
&ulProfProps,
&lpProfProps);
if (SUCCEEDED(hRes))
{
CSupport * pMySup = NULL;
pMySup = new CSupport(lpMAPISup, lpProfSect);
if (!pMySup)
{
Log(true,"MSProviderInit: Failed to allocate new CSupport object\n");
hRes = E_OUTOFMEMORY;
}
if (SUCCEEDED(hRes))
{
hRes = pNSTServiceEntry(
hm,
lpMalloc,
pMySup,
ulUIParam,
ulFlags,
ulContext,
ulProfProps,
lpProfProps,
NULL,//pAdminProvObj, //Don't pass this when creating an NST
lppMapiError);
if (SUCCEEDED(hRes))
{
// Finish setting up the profile
hRes = InitStoreProps(
lpMAPISup,
lpProfSect,
lpProviderAdmin);
hRes = lpProfSect->SaveChanges(KEEP_OPEN_READWRITE);
}
}
}
Log(true, "Ran pNSTServiceEntry 0x%08X\n", hRes);
MyFreeBuffer(lpProfProps);
if (lpProfSect) lpProfSect->Release();
return hRes;
}