ISTORE.C

// --istore.c------------------------------------------------------------------- 
//
// Module containing MAPI utility functions for message stores.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------

#include "edk.h"

#include "istore.chk"

// $--HrMAPIFindStore@----------------------------------------------------------
//
// DESCRIPTION:Find an MDB store based on a string.
//
// INPUT:
//
// [lpSession]-- MAPI session ptr.
// [lpszStore]-- Store name (PR_DISPLAY_NAME).
//
// OUTPUT:
//
// [lpcbentryid]-- Number of bytes in store's entry identifier.
// [lppentryid]-- Ptr to store entry identifier.
//
// RETURNS: NOERRORif successful;
//E_INVALIDARGif bad input;
//E_OUTOFMEMORYif not enough memory;
//EDK_E_NOT_FOUNDif specified store not found;
// E_FAILotherwise.
//
//---------------------------------------------------------------------------
HRESULT HrMAPIFindStoreW(
INLPMAPISESSIONlpSession, // MAPI session ptr
INLPCWSTRlpszStore, // store name
OUTULONG FAR *lpcbentryid, // ptr to # byte in entry ID
OUTLPENTRYID FAR *lppentryid)// entry ID buffer ptr
{
HRESULThr = NOERROR;
LPSTR lpszStoreA = NULL;

DEBUGPUBLIC( "HrMAPIFindStoreW()");

hr = CHK_HrMAPIFindStoreW( lpSession, lpszStore, lpcbentryid, lppentryid);
if (FAILED(hr))
RETURN(hr);

// Because MAPI doesn't officially support UNICODE strings, we are forced
// to do a string conversion and call the other function...
hr = HrStrWToStrA( lpszStore, &lpszStoreA);
if( FAILED( hr))
goto cleanup;

hr = HrMAPIFindStoreA( lpSession, lpszStoreA, lpcbentryid, lppentryid);

cleanup:
MAPIFREEBUFFER( lpszStoreA);

RETURN(hr);
}

HRESULT HrMAPIFindStoreA(
INLPMAPISESSIONlpSession, // MAPI session ptr
INLPCSTRlpszStore, // store name
OUTULONG FAR *lpcbentryid, // ptr to # byte in entry ID
OUTLPENTRYID FAR *lppentryid)// entry ID buffer ptr
{
HRESULThr = NOERROR;
LPMAPITABLElpTable = NULL;
LPSRowSetlpRow = NULL;
LPSPropValue lpProp = NULL;

static SizedSPropTagArray( 1, EntryID) = { 1, { PR_ENTRYID}};
static SPropValue RestrictProp = { PR_DISPLAY_NAME_A, 0L, { 0}};
static SRestriction Restriction = { RES_PROPERTY, { RELOP_EQ, PR_DISPLAY_NAME_A, (ULONG)&RestrictProp}};

DEBUGPUBLIC( "HrMAPIFindStoreA()");

hr = CHK_HrMAPIFindStoreA( lpSession, lpszStore, lpcbentryid, lppentryid);
if (FAILED(hr))
RETURN(hr);

// Set name of the store name to find.
RestrictProp.Value.lpszA = (LPSTR)lpszStore;

hr = MAPICALL( lpSession)->GetMsgStoresTable( lpSession,
0L, &lpTable);
if (FAILED(hr))
{
hr = HR_LOG( E_FAIL);
goto cleanup;
}

hr = HrQueryAllRows(
lpTable, (LPSPropTagArray)&EntryID,
&Restriction, NULL, 0, &lpRow);
if( FAILED( hr))
{
if( hr == MAPI_E_NOT_FOUND)
hr = HR_LOG( EDK_E_NOT_FOUND);
else
hr = HR_LOG( E_FAIL);

goto cleanup;
}

if (lpRow == NULL || lpRow->cRows != 1)
{
hr = HR_LOG( E_FAIL);
goto cleanup;
}

lpProp = &lpRow->aRow[0].lpProps[0];

hr = MAPIAllocateBuffer(lpProp->Value.bin.cb, (LPVOID FAR *)lppentryid);
if (FAILED(hr))
{
hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}

memcpy(*lppentryid, lpProp->Value.bin.lpb, lpProp->Value.bin.cb);
*lpcbentryid = lpProp->Value.bin.cb;

cleanup:
FREEPROWS(lpRow);
ULRELEASE(lpTable);

RETURN(hr);
}

//$--HrMAPIFindDefaultMsgStore----------------------------------------------------
// Get the entry ID of the default message store.
// -----------------------------------------------------------------------------
HRESULT HrMAPIFindDefaultMsgStore( // RETURNS: return code
IN LPMAPISESSION lplhSession, // session pointer
OUT ULONG *lpcbeid, // count of bytes in entry ID
OUT LPENTRYID *lppeid) // entry ID of default store
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
SCODE sc = 0;
LPMAPITABLE lpTable = NULL;
LPSRowSet lpRows = NULL;
LPENTRYID lpeid = NULL;
ULONG cbeid = 0;
ULONG cRows = 0;
ULONG i = 0;

SizedSPropTagArray(2, rgPropTagArray) =
{
2,
{
PR_DEFAULT_STORE,
PR_ENTRYID
}
};

DEBUGPUBLIC("HrMAPIFindDefaultMsgStore()\n");

hr = CHK_HrMAPIFindDefaultMsgStore(
lplhSession,
lpcbeid,
lppeid);

if(FAILED(hr))
RETURN(hr);

// Get the list of available message stores from MAPI

hrT = MAPICALL(lplhSession)->GetMsgStoresTable(lplhSession, 0, &lpTable);

if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

// Get the row count for the message recipient table
hrT = MAPICALL(lpTable)->GetRowCount(lpTable, 0, &cRows);

if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

// Set the columns to return
hrT = MAPICALL(lpTable)->SetColumns(lpTable, (LPSPropTagArray)&rgPropTagArray, 0);

if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

// Go to the beginning of the recipient table for the envelope
hrT = MAPICALL(lpTable)->SeekRow(lpTable, BOOKMARK_BEGINNING, 0, NULL);

if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

// Read all the rows of the table
hrT = MAPICALL(lpTable)->QueryRows(lpTable, cRows, 0, &lpRows);

if(SUCCEEDED(hrT) && (lpRows != NULL) && (lpRows->cRows == 0))
{
FREEPROWS(lpRows);

hrT = EDK_E_NOT_FOUND;
}

if(FAILED(hrT) || (lpRows == NULL))
{
if(hrT != EDK_E_NOT_FOUND)
{
hr = HR_LOG(E_FAIL);
}
else
{
hr = HR_LOG(EDK_E_NOT_FOUND);
}

goto cleanup;
}


for(i = 0; i < cRows; i++)
{
if(lpRows->aRow[i].lpProps[0].Value.b == TRUE)
{
cbeid = lpRows->aRow[i].lpProps[1].Value.bin.cb;

sc = MAPIAllocateBuffer(cbeid, (void **)&lpeid);

if(FAILED(sc))
{
cbeid = 0;
lpeid = NULL;

hr = HR_LOG(E_OUTOFMEMORY);
goto cleanup;
}

// Copy entry ID of message store
CopyMemory(
lpeid,
lpRows->aRow[i].lpProps[1].Value.bin.lpb,
cbeid);

break;
}
}

if(lpeid == NULL)
{
hr = HR_LOG(E_FAIL);
}

ASSERTERROR(cbeid != 0, "ZERO cbeid variable");

ASSERT_READ_PTR(lpeid, cbeid, "INVALID lpeid variable");

cleanup:

if(lpRows != NULL)
{
FreeProws(lpRows);
}

ULRELEASE(lpTable);

*lpcbeid = cbeid;
*lppeid = lpeid;

RETURN(hr);
}


//$--FIsPublicStore------------------------------------------------------------
// Returns TRUE if the MDB is a public store.
// -----------------------------------------------------------------------------
BOOL FIsPublicStore(
IN LPMDB lpmdb) // pointer to message store

{
BOOL bIsPublic = FALSE;
HRESULT hrT = NOERROR;
ULONG cValues = 0;
LPSPropValue lpPropValue = NULL;
ULONG cbeid = 0;

static SPropTagArray rgPropTag = { 1, { PR_MDB_PROVIDER } };

DEBUGPUBLIC( "FIsPublicStore()");

hrT = CHK_FIsPublicStore( lpmdb);
if(FAILED(hrT))
return(FALSE);

// Get the property.
hrT = MAPICALL(lpmdb)->GetProps( lpmdb,
&rgPropTag,
fMapiUnicode,
&cValues,
&lpPropValue);

if(FAILED(hrT) || hrT == MAPI_W_ERRORS_RETURNED)
{
HR_LOG(E_FAIL);
goto cleanup;
}

ASSERTERROR(cValues != 0, "ZERO cValues variable");

ASSERTERROR(lpPropValue != NULL, "NULL lpPropValue variable");

// Check to make sure we got the right property.
if (lpPropValue->ulPropTag != PR_MDB_PROVIDER)
{
HR_LOG(E_FAIL);
goto cleanup;
}

// See if PR_MDB_PROVIDER == pbExchangeProviderPublicGuid

if ( (lpPropValue->Value.bin.cb == sizeof(GUID)) &&
(memcmp(lpPropValue->Value.bin.lpb,
pbExchangeProviderPublicGuid, sizeof(GUID)) == 0) )
{
bIsPublic = TRUE;
}

cleanup:

MAPIFREEBUFFER(lpPropValue);

return(bIsPublic);
}

//$--_HrOpenStoreFromGuid-------------------------------------------------------
// Locates the store provider based on GUID and returns open interface pointer
//------------------------------------------------------------------------------
HRESULT _HrOpenStoreFromGuid (
IN LPMAPISESSION lphSession,
IN LPGUID pbStoreProviderGuid,
OUT LPMDB *lppMDB)
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
LPMAPITABLE lpTable = NULL;
LPSRowSet lpRows = NULL;

static SPropTagArray aptEntryID = { 1, { PR_ENTRYID } };
static SPropValue SProp = { PR_MDB_PROVIDER, 0L, { 0}};
static SRestriction SRestrict = { RES_PROPERTY,
{ RELOP_EQ, PR_MDB_PROVIDER, (LONG)&SProp } };

DEBUGPRIVATE("_HrOpenStoreFromGuid()");

hr = CHK_HrOpenStoreFromGuid( lphSession, pbStoreProviderGuid, lppMDB);
if(FAILED(hr))
RETURN(hr);

// Clear return value

*lppMDB = NULL;

// Get table of message stores

hrT = MAPICALL(lphSession)->GetMsgStoresTable(lphSession, 0, &lpTable);
if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

// Restrict the table to the appropriate Exchange store
SProp.Value.bin.cb = sizeof(GUID);
SProp.Value.bin.lpb = (LPBYTE)pbStoreProviderGuid;

hrT = HrQueryAllRows( lpTable, &aptEntryID, &SRestrict, NULL, 0L, &lpRows);
if(FAILED(hrT) || (lpRows->cRows == 0))
{
if((hrT == MAPI_E_NOT_FOUND) ||
((hrT == SUCCESS_SUCCESS) && (lpRows->cRows == 0)))
{
hr = HR_LOG(EDK_E_NOT_FOUND);
}
else
{
hr = HR_LOG(E_FAIL);
}

goto cleanup;
}

if((lpRows->aRow->cValues != 1) ||
(lpRows->aRow->lpProps[0].ulPropTag != PR_ENTRYID))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

// Open the message store

hrT = MAPICALL(lphSession)->OpenMsgStore(
lphSession,
(ULONG)0,
lpRows->aRow->lpProps[0].Value.bin.cb,
(LPENTRYID)lpRows->aRow->lpProps[0].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
lppMDB);

if(FAILED(hrT))
{
hr = HR_LOG(E_FAIL);
goto cleanup;
}

cleanup:

FREEPROWS(lpRows);

ULRELEASE(lpTable);

RETURN(hr);
}