I´m trying to develop a custom address book provider for outlook.
Using MFCMAPI to browse the store I found that the PR_PST_PATH
property for the .pst file of the outlook default profile is reachable through IProviderAdmin-Interface.
So I tried the following piece of mapi-code:
// Get ProfileAdmin
LPPROFADMIN lpProfileAdmin = NULL;
hRes = MAPIAdminProfiles(0, &lpProfileAdmin);
if (FAILED(hRes) || lpProfileAdmin == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
// Get ProfileTable and filter default profile
LPMAPITABLE lpProfileTable = NULL;
hRes = lpProfileAdmin->GetProfileTable(0, &lpProfileTable);
if (FAILED(hRes) || lpProfileTable == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
SPropValue spvDefaultProfile;
spvDefaultProfile.ulPropTag = PR_DEFAULT_PROFILE;
spvDefaultProfile.Value.b = TRUE;
SRestriction srProfile;
srProfile.rt = RES_PROPERTY;
srProfile.res.resProperty.relop = RELOP_EQ;
srProfile.res.resProperty.ulPropTag = PR_DEFAULT_PROFILE;
srProfile.res.resProperty.lpProp = &spvDefaultProfile;
hRes = lpProfileTable->Restrict(&srProfile, TBL_BATCH);
hRes = lpProfileTable->FindRow(&srProfile, BOOKMARK_BEGINNING, 0);
LPSRowSet lpRowSet = NULL;
hRes = lpProfileTable->QueryRows(1, 0, &lpRowSet);
if (FAILED(hRes) || lpRowSet == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
bstr_t profileName((const char *)lpRowSet->aRow[0].lpProps[0].Value.lpszA);
lpzProfileName = (LPTSTR)profileName;
// Get ServiceAdmin
LPSERVICEADMIN lpServiceAdmin = NULL;
hRes = lpProfileAdmin->AdminServices(lpzProfileName, NULL, NULL, MAPI_UNICODE, &lpServiceAdmin);
if (FAILED(hRes) || lpServiceAdmin == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
// Get ServiceTable and filter default store
LPMAPITABLE lpServiceTable = NULL;
hRes = lpServiceAdmin->GetMsgServiceTable(0, &lpServiceTable);
if (FAILED(hRes) || lpServiceTable == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
SRestriction srService;
srService.rt = RES_BITMASK;
srService.res.resBitMask.ulPropTag = PR_RESOURCE_FLAGS;
srService.res.resBitMask.relBMR = BMR_EQZ;
srService.res.resBitMask.ulMask = SERVICE_DEFAULT_STORE;
hRes = lpServiceTable->Restrict(&srService, TBL_BATCH);
hRes = lpServiceTable->FindRow(&srService, BOOKMARK_BEGINNING, 0);
lpRowSet = NULL;
hRes = lpServiceTable->QueryRows(1, 0, &lpRowSet);
if (FAILED(hRes) || lpRowSet == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
// Get UID Property for default store
LPSPropValue pValServiceUid = PpropFindProp(lpRowSet->aRow[0].lpProps, lpRowSet->aRow[0].cValues, PR_SERVICE_UID);
if (pValServiceUid == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
// Get ProfileSection for UID
LPPROFSECT lpProfileSect = NULL;
hRes = lpServiceAdmin->OpenProfileSection((LPMAPIUID)pValServiceUid->Value.bin.lpb, NULL, MAPI_FORCE_ACCESS, &lpProfileSect);
if (FAILED(hRes) || lpProfileSect == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
// Get UID of IProviderAdmin
LPSPropValue pValProviderUid = NULL;
hRes = HrGetOneProp(lpProfileSect, PR_STORE_PROVIDERS, &pValProviderUid);
if (FAILED(hRes) || pValProviderUid == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
LPPROVIDERADMIN lpProviderAdmin = NULL;
hRes = lpServiceAdmin->AdminProviders((LPMAPIUID)pValProviderUid->Value.bin.lpb, 0, &lpProviderAdmin);
if (FAILED(hRes) || lpProviderAdmin == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
LPMAPITABLE lpProviderTable = NULL;
hRes = lpProviderAdmin->GetProviderTable(0, &lpProviderTable);
if (FAILED(hRes) || lpProviderTable == NULL) {
hRes = MAPI_E_UNCONFIGURED;
return hRes;
}
But the call to
lpServiceAdmin->AdminProviders(...)
fails with a return value of E_INVALIDARGS
.
So, what I´m doing wrong? And what is the correct way to get the PR_PST_PATH
property?
Regards
Joachim