Initialisieren eines Anbieters von umschlossenem PST-Speicher
Gilt für: Outlook 2013 | Outlook 2016
Um einen umschlossenen PST-Speicheranbieter (Personal Folders File) zu implementieren, müssen Sie den umschlossenen PST-Speicheranbieter initialisieren, indem Sie die MSProviderInit-Funktion als Einstiegspunkt verwenden. Nachdem die DLL des Anbieters initialisiert wurde, konfiguriert die MSGSERVICEENTRY-Funktion den umschlossenen PST-Speicheranbieter.
In diesem Thema werden die MSProviderInit-Funktion und die MSGSERVICEENTRY-Funktion anhand von Codebeispielen aus dem Beispiel für umschlossenen PST-Speicheranbieter veranschaulicht. Das Beispiel implementiert einen umschlossenen PST-Anbieter, der zusammen mit der Replikations-API verwendet werden soll. Weitere Informationen zum Herunterladen und Installieren des Beispielanbieters für umschlossenen PST-Speicher finden Sie unter Installieren des Beispielanbieters für umschlossenen PST-Speicher. Weitere Informationen zur Replikations-API finden Sie unter Informationen zur Replikations-API.
Nachdem Sie einen umschlossenen PST-Speicheranbieter initialisiert haben, müssen Sie Funktionen implementieren, damit MAPI und der MAPI-Spooler sich beim Nachrichtenspeicheranbieter anmelden können. Weitere Informationen finden Sie unter Anmelden bei einem umschlossenen PST-Speicheranbieter.
Initialisierungsroutine
Alle umschlossenen PST-Speicheranbieter müssen die MSProviderInit-Funktion als Einstiegspunkt implementieren, um die DLL des Anbieters zu initialisieren.
MSProviderInit überprüft, ob die Versionsnummer der Dienstanbieterschnittstelle ( ulMAPIVer
) mit der aktuellen Versionsnummer CURRENT_SPI_VERSION
kompatibel ist. Die Funktion speichert die MAPI-Speicherverwaltungsroutinen in den g_lpAllocateBuffer
Parametern , g_lpAllocateMore
und g_lpFreeBuffer
. Diese Speicherverwaltungsroutinen sollten während der gesamten Implementierung des umschlossenen PST-Speichers für die Speicherbelegung und -freigabe verwendet werden.
MSProviderInit()-Beispiel
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;
}
Umschlossene PST- und Unicode-Pfade
Um das in Microsoft Visual Studio 2008 vorbereitete originale Beispiel zur Verwendung von Unicode-Pfaden zur NST für die Verwendung in Unicode-fähigen Microsoft Outlook 2010 und Outlook 2013 nachzurüsten, sollte die CreateStoreEntryID-Routine, die den Eintragsbezeichner erzeugt, ein Format für ASCII-Pfade und ein anderes für Unicode-Pfade verwenden. Diese werden im folgenden Beispiel als Strukturen dargestellt.
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;
Wichtig
Die Unterschiede in diesen Strukturen sind zwei NULL-Bytes vor einem Unicode-Pfad. Wenn Sie den Eintragsbezeichner in der folgenden "Diensteintragsroutine" interpretieren müssen, können Sie ermitteln, ob dies der Fall ist oder nicht, zuerst in EIDMS umgewandelt werden. Überprüfen Sie dann, ob szPath[0] NULL ist. Wenn dies der Grund ist, wandeln Sie es stattdessen in EIDMSW um.
Diensteintragsroutine
Die MSGSERVICEENTRY-Funktion ist der Einstiegspunkt für den Nachrichtendienst, an dem der umschlossene PST-Speicheranbieter konfiguriert ist. Die Funktion ruft auf GetMemAllocRoutines()
, um die MAPI-Speicherverwaltungsroutinen abzurufen. Die Funktion verwendet den lpProviderAdmin
-Parameter, um den Profilabschnitt für den Anbieter zu suchen und legt die Eigenschaften im Profil fest.
ServiceEntry()-Beispiel
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;
}