Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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_VERSIONkompatibel ist. Die Funktion speichert die MAPI-Speicherverwaltungsroutinen in den g_lpAllocateBufferParametern , g_lpAllocateMoreund 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;
}