OpenMsgStore fails with MAPI_E_FAILONEPROVIDER



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(&ltime);
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

.



Relevant Pages

  • Re: MAPI Error in Exchange Server 2007
    ... Was this profile already created, and if so is it an Online profile? ... // Pointer to entry ID of message store. ... // Clean up memory and uninitialize MAPI. ...
    (microsoft.public.exchange.admin)
  • Re: OpenMsgStore fails with MAPI_E_FAILONEPROVIDER
    ... It creates a dynamic profile and logs into ... Handle to parent window. ... // and getting the entry that corresponds to the new service. ... It then opens the message store using this function but it fails on ...
    (microsoft.public.win32.programmer.messaging)
  • Re: User Profiles Windows XP Professional
    ... security which has to be changed from the local user account to the domain ... When you look at the location of the original users profile you will find it ... inside a folder with a very long alphanumeric folder name enclosed by. ... OE does not support a message store contained ...
    (microsoft.public.windowsxp.security_admin)
  • Re: how to share a profile
    ... I would like to have my regular exchange ... > profile sync with the RPC profile, so that the mail in both profiles ... both should acess the same message store. ...
    (microsoft.public.outlook.general)
  • Re: Outlook 2003 and XP SP2
    ... profile, ... You can only have one exchange account ... Diane Poremsky [MVP - Outlook] ... Outlook & Exchange Solutions Center: http://www.slipstick.com ...
    (microsoft.public.office.setup)

Loading