Re: OpenMsgStore fails with MAPI_E_FAILONEPROVIDER
- From: "Dmitry Streblechenko" <dmitry@xxxxxxxxxxx>
- Date: Tue, 4 Sep 2007 12:01:29 -0700
Is the code running under the Windows user identity of the mailbox owner?
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
"Paul" <paul_keeley@xxxxxxxxxxxxx> wrote in message
news:1188930979.254744.319240@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
We have an email archival product written in Java that connects to
Exchange using JNI and MAPI. On all of our test servers it works fine
but at a customer site it is throwing MAPI_E_FAILONEPROVIDER on the
OpenMsgStore call. It creates a dynamic profile and logs into
exchange when the service starts using this function.
void MAPIHelpers::MAPILogon(const char * serverName, const char *
userName, CComPtr<IMAPISession> &mapiSession)
{
static CComMultiThreadModel::AutoCriticalSection criticalSection;
CComCritSecLock<CComMultiThreadModel::AutoCriticalSection>
lock(criticalSection);
HRESULT hRes = S_OK; // Result from MAPI calls.
CComPtr<IProfAdmin> lpProfAdmin; // Profile Admin object.
CComPtr<IMsgServiceAdmin> lpSvcAdmin; // Service Admin object.
CComPtr<IMAPITable> lpMsgSvcTable;
CMAPIObject<SRowSet> lpSvcRows;
SPropValue rgval[4]; // Property structure to
hold values we want to set.
SRestriction sres; // Restriction structure.
SPropValue SvcProps; // Property structure for
restriction.
char profile[_MAX_PATH];
// Create a unique profile name - so new profile gets created
// everytime it runs - no conflict with previous profile if
// process is shutdown and restarted
time_t ltime;
time(<ime);
sprintf(profile, "%s_%s_%s_%ld", "espmstr",serverName, userName,
ltime);
// This indicates columns we want returned from HrQueryAllRows.
enum {iSvcName, iSvcUID, cptaSvc};
SizedSPropTagArray(cptaSvc, sptCols) = { cptaSvc, PR_SERVICE_NAME,
PR_SERVICE_UID };
// Get an IProfAdmin interface.
if (FAILED(hRes = MAPIAdminProfiles(0, // Flags.
&lpProfAdmin))) // Pointer to
new IProfAdmin.
{
throw CEmailException(__LINE__, hRes, "MAPIAdminProfiles call
failed");
}
//Delete profile before
lpProfAdmin->DeleteProfile((LPTSTR) profile, 0);
// Create a new profile.
if (FAILED(hRes = lpProfAdmin->CreateProfile(profile, // Name of
new profile.
NULL, // Password
for profile.
NULL, //
Handle to parent window.
NULL))) //
Flags.
{
if (hRes == MAPI_E_NO_ACCESS) {
if (FAILED(hRes = MAPILogonEx(0, profile, NULL,
// MAPI_ALLOW_OTHERS |
MAPI_NT_SERVICE |
MAPI_EXTENDED |
MAPI_NO_MAIL |
MAPI_NEW_SESSION, &mapiSession)))
{
lpProfAdmin->DeleteProfile(profile, 0);
throw CEmailException(__LINE__, hRes, "MAPILogonEx failed");
};
lpProfAdmin->DeleteProfile(profile, 0);
return;
}
else
throw CEmailException(__LINE__, hRes, "Unable to create profile");
}
// Get an IMsgServiceAdmin interface off of the IProfAdmin
interface.
if (FAILED(hRes = lpProfAdmin->AdminServices(profile, // Profile
that we want to modify.
NULL, // Password for
that profile.
NULL, //
Handle to parent window.
0, //
Flags.
&lpSvcAdmin))) //
Pointer to new IMsgServiceAdmin.
{
// cout<<"Error getting IMsgServiceAdmin interface.";
lpProfAdmin->DeleteProfile(profile, 0);
throw CEmailException(__LINE__, hRes, "Unable to get
AdminServices");
}
// Create the new message service for Exchange.
if (FAILED(hRes = lpSvcAdmin->CreateMsgService("MSEMS", //
Name of service from MAPISVC.INF.
NULL, //
Display name of service.
NULL, //
Handle to parent window.
NULL))) //
Flags.
{
// cout<<"Error creating Exchange message service.";
lpProfAdmin->DeleteProfile(profile, 0);
throw CEmailException(__LINE__, hRes, "Unable to create message
service");
}
// We now need to get the entry id for the new service.
// This can be done by getting the message service table
// and getting the entry that corresponds to the new service.
if (FAILED(hRes = lpSvcAdmin-
GetMsgServiceTable(0, // Flags.
&lpMsgSvcTable))) // Pointer to table.
{
// cout<<"Error getting Message Service Table.";
lpProfAdmin->DeleteProfile(profile, 0);
throw CEmailException(__LINE__, hRes, "Unable to
GetMsgServiceTable");
}
// Set up restriction to query table.
sres.rt = RES_CONTENT;
sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING;
sres.res.resContent.ulPropTag = PR_SERVICE_NAME;
sres.res.resContent.lpProp = &SvcProps;
SvcProps.ulPropTag = PR_SERVICE_NAME;
SvcProps.Value.lpszA = "MSEMS";
// Query the table to get the entry for the newly created message
service.
if (FAILED(hRes = HrQueryAllRows(lpMsgSvcTable,
(LPSPropTagArray)&sptCols,
&sres,
NULL,
0,
&lpSvcRows)))
{
// cout<<"Error querying table for new message service.";
lpProfAdmin->DeleteProfile(profile, 0);
throw CEmailException(__LINE__, hRes, "Unable to query table");
}
// Setup a SPropValue array for the properties you need to
configure.
// First, the server name.
ZeroMemory(&rgval[1], sizeof(SPropValue) );
rgval[1].ulPropTag = PR_PROFILE_UNRESOLVED_SERVER;
rgval[1].Value.lpszA = (char*)serverName;
// Next, the mailbox name.
ZeroMemory(&rgval[0], sizeof(SPropValue) );
rgval[0].ulPropTag = PR_PROFILE_UNRESOLVED_NAME;
rgval[0].Value.lpszA = (char*)userName;
ZeroMemory(&rgval[2], sizeof(SPropValue));
rgval[2].ulPropTag = PR_PROFILE_CONNECT_FLAGS;
rgval[2].Value.l = CONNECT_USE_ADMIN_PRIVILEGE;
ZeroMemory(&rgval[3], sizeof(SPropValue));
rgval[3].ulPropTag = PR_PROFILE_CONFIG_FLAGS;
rgval[3].Value.l = CONFIG_SERVICE;
// Configure the message service with the above properties.
if (FAILED(hRes = lpSvcAdmin->ConfigureMsgService(
(LPMAPIUID)lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.lpb, //
Entry ID of service to configure.
NULL, //
Handle to parent window.
0, //
Flags.
4, //
Number of properties we are setting.
rgval))) //
Pointer to SPropValue array.
{
// cout<<"Error configuring message service.";
lpProfAdmin->DeleteProfile(profile, 0);
std::ostringstream o;
o << "Unable to configure message service on " << serverName << "
for user " << userName;
throw CEmailException(__LINE__, hRes, o.str().c_str());
}
if (FAILED(hRes = MAPILogonEx(0, profile, NULL,
// MAPI_ALLOW_OTHERS |
MAPI_NT_SERVICE |
MAPI_EXTENDED |
MAPI_NO_MAIL |
MAPI_NEW_SESSION, &mapiSession)))
{
lpProfAdmin->DeleteProfile(profile, 0);
throw CEmailException(__LINE__, hRes, "MAPILogonEx failed");
};
lpProfAdmin->DeleteProfile(profile, 0);
}
It then opens the message store using this function but it fails on
the OpenMsgBox call. Admittedly I should check for a returned row
before calling OpenMsgBox but why would there be no row or why would
OpenMsgBox fail?
CExchangeMailBox * CExchangeServer::openDefaultMailBox()
{
assert(m_mapiSession.p);
CComPtr<IMAPITable> pStoresTbl;
CMAPIObject<SRowSet> pRow;
SRestriction sres;
SPropValue spv;
HRESULT hRes;
CComPtr<IMsgStore> lpTempMDB;
enum {EID, NAME, NUM_COLS};
SizedSPropTagArray(NUM_COLS,sptCols) = {NUM_COLS, PR_ENTRYID,
PR_DISPLAY_NAME};
//Get the table of all the message stores available
hRes = m_mapiSession->GetMsgStoresTable(0, &pStoresTbl);
if (FAILED(hRes)) {
throw CEmailException(__LINE__, hRes, "Failed to get message stores
table");
};
//Set up restriction for the default store
sres.rt = RES_PROPERTY; //Comparing a property
sres.res.resProperty.relop = RELOP_EQ; //Testing equality
sres.res.resProperty.ulPropTag = PR_DEFAULT_STORE; //Tag to compare
sres.res.resProperty.lpProp = &spv; //Prop tag and value to compare
against
spv.ulPropTag = PR_DEFAULT_STORE; //Tag type
spv.Value.b = TRUE; //Tag value
//Convert the table to an array which can be stepped through
//Only one message store should have PR_DEFAULT_STORE set to true,
so only one will be returned
hRes = HrQueryAllRows(
pStoresTbl, //Table to query
(LPSPropTagArray) &sptCols, //Which columns to get
&sres, //Restriction to use
NULL, //No sort order
0, //Max number of rows (0 means no limit)
&pRow); //Array to return
if (FAILED(hRes) ){
throw CEmailException(__LINE__, hRes, "Failed querying message
stores table");
};
//Open the first returned (default) message store
hRes = m_mapiSession->OpenMsgStore(
NULL,//Window handle for dialogs
pRow->aRow[0].lpProps[EID].Value.bin.cb,//size and...
(LPENTRYID)pRow->aRow[0].lpProps[EID].Value.bin.lpb,//value of
entry to open
NULL,//Use default interface (IMsgStore) to open store
MAPI_BEST_ACCESS | MDB_TEMPORARY | MDB_NO_MAIL |
MDB_NO_DIALOG ,//Flags
&lpTempMDB);//Pointer to place the store in
if (FAILED(hRes)) {
throw CEmailException(__LINE__, hRes, "Failed opening message
store");
};
//Assign the out parameter
return new CExchangeMailBox(this, lpTempMDB);
}
Thanks,
Paul
.
- Follow-Ups:
- References:
- Prev by Date: OpenMsgStore fails with MAPI_E_FAILONEPROVIDER
- Next by Date: Re: OpenMsgStore fails with MAPI_E_FAILONEPROVIDER
- Previous by thread: OpenMsgStore fails with MAPI_E_FAILONEPROVIDER
- Next by thread: Re: OpenMsgStore fails with MAPI_E_FAILONEPROVIDER
- Index(es):
Relevant Pages
|