Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

778 lines
16 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
cmapiabobj.cpp
Abstract:
Interface to the MAPI address book.
Environment:
Fax send wizard
Revision History:
--*/
#include <windows.h>
#include <prsht.h>
#include <tchar.h>
#include <mapiwin.h>
#include <mapix.h>
#include <mapiutil.h>
#include <mapi.h>
#include "faxui.h"
#include "mapiabobj.h"
#include <mapitags.h>
#include "edkmdb.h"
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
// initialize static variables
HINSTANCE CMAPIabObj::m_hInstMapi = NULL;
LPMAPISESSION CMAPIabObj::m_lpMapiSession = NULL;
LPMAPILOGONEX CMAPIabObj::m_lpfnMAPILogonEx = NULL;
LPMAPILOGOFF CMAPIabObj::m_lpfnMAPILogoff = NULL;
LPMAPIADDRESS CMAPIabObj::m_lpfnMAPIAddress = NULL;
LPMAPIFREEBUFFER CMAPIabObj::m_lpfnMAPIFreeBuffer = NULL;
LPMAPIINITIALIZE CMAPIabObj::m_lpfnMAPIInitialize = NULL;
LPMAPIUNINITIALIZE CMAPIabObj::m_lpfnMAPIUninitialize = NULL;
LPMAPIALLOCATEBUFFER CMAPIabObj::m_lpfnMAPIAllocateBuffer = NULL;
LPMAPIALLOCATEMORE CMAPIabObj::m_lpfnMAPIAllocateMore = NULL;
LPMAPIADMINPROFILES CMAPIabObj::m_lpfnMAPIAdminProfiles = NULL;
LPHrQueryAllRows CMAPIabObj::m_lpfnHrQueryAllRows = NULL;
BOOL CMAPIabObj::m_Initialized = FALSE;
CMAPIabObj::CMAPIabObj(
HINSTANCE hInstance,
HWND hDlg
) : CCommonAbObj(hInstance)
/*++
Routine Description:
Constructor for CMAPIabObj class
Arguments:
hInstance - Instance handle
Return Value:
NONE
--*/
{
m_Initialized = InitMapiService(hDlg);
}
VOID
CMAPIabObj::FreeProws(
LPSRowSet prows
)
/*++
Routine Description:
Destroy SRowSet structure. Copied from MAPI.
Arguments:
hFile - Pointer to SRowSet
Return value:
NONE
--*/
{
ULONG irow;
if (!prows) {
return;
}
for (irow = 0; irow < prows->cRows; ++irow) {
m_lpfnMAPIFreeBuffer(prows->aRow[irow].lpProps);
}
m_lpfnMAPIFreeBuffer( prows );
}
BOOL
CMAPIabObj::GetDefaultMapiProfile(
OUT LPSTR ProfileName,
IN UINT cchProfileName
)
{
BOOL rVal = FALSE;
LPMAPITABLE pmt = NULL;
LPSRowSet prws = NULL;
LPSPropValue pval;
LPPROFADMIN lpProfAdmin;
DWORD i;
DWORD j;
if (FAILED(m_lpfnMAPIAdminProfiles(0, &lpProfAdmin )))
{
goto exit;
}
//
// get the mapi profile table object
//
if (FAILED(lpProfAdmin->GetProfileTable(0, &pmt )))
{
goto exit;
}
//
// get the actual profile data, FINALLY
//
if (FAILED(pmt->QueryRows( 4000, 0, &prws )))
{
goto exit;
}
//
// enumerate the profiles looking for the default profile
//
for (i=0; i<prws->cRows; i++)
{
pval = prws->aRow[i].lpProps;
for (j = 0; j < 2; j++)
{
if (pval[j].ulPropTag == PR_DEFAULT_PROFILE && pval[j].Value.b)
{
//
// this is the default profile
//
if(FAILED(StringCchCopyA(ProfileName, cchProfileName, pval[0].Value.lpszA)))
{
goto exit;
}
rVal = TRUE;
break;
}
}
}
exit:
FreeProws( prws );
if (pmt)
{
pmt->Release();
}
if (lpProfAdmin)
{
lpProfAdmin->Release();
}
return rVal;
}
BOOL
CMAPIabObj::DoMapiLogon(
HWND hDlg
)
/*++
Routine Description:
Logon MAPI to in order to access address book
Arguments:
hDlg - Handle to the send fax wizard window
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{
CHAR strProfileName[MAX_PROFILE_NAME];
HRESULT status;
status = m_lpfnMAPIInitialize(NULL);
if (status != SUCCESS_SUCCESS)
return FALSE;
if (!GetDefaultMapiProfile(strProfileName, ARR_SIZE(strProfileName)))
{
m_lpfnMAPIUninitialize();
return FALSE;
}
status = m_lpfnMAPILogonEx((ULONG_PTR) hDlg,
(LPTSTR)strProfileName,
NULL,
MAPI_USE_DEFAULT,
&m_lpMapiSession);
if (status != SUCCESS_SUCCESS || !m_lpMapiSession )
{
m_lpfnMAPIUninitialize();
return FALSE;
}
OpenExchangeStore(); // If it fails it might just indicate that exchagne is not here.
// We don't fail the function in this case.
status = m_lpMapiSession->OpenAddressBook((ULONG_PTR) hDlg,
NULL,
0,
&m_lpAdrBook);
if (HR_FAILED(status) || !m_lpAdrBook)
{
if (m_lpMapiSession)
{
m_lpMapiSession->Logoff(0,0,0);
m_lpMapiSession->Release();
m_lpIMsgStore->Release();
}
m_lpIMsgStore=NULL;
m_lpMapiSession = NULL;
m_lpfnMAPIUninitialize();
return FALSE;
}
return TRUE;
}
BOOL CMAPIabObj::OpenExchangeStore()
{
/*++
Routine Description:
Open the Exchange message store and place a pointer to the IMsgStore interface
in CMAPIabObj::m_lpIMsgStore.
This is done to keep the store loaded as long as we have the address book opened.
This resolves an exchange issue where sometimes the address book is released
alrhough we still have reference count on its interfaces.
Arguments:
None
Return Value:
TRUE if successful, FALSE if there is an error
--*/
ULONG ulRow=0;
HRESULT hr = S_OK;
LPMAPITABLE lpStoreTable = NULL;
LPSRowSet lprowsStores = NULL;
SizedSPropTagArray(3, propStoreProperties)=
{
3,
{PR_DISPLAY_NAME_A, PR_ENTRYID, PR_MDB_PROVIDER}
};
hr = m_lpMapiSession->GetMsgStoresTable(
0, // NO UNICODE
&lpStoreTable);
if (FAILED(hr))
{
Error(("IMAPISession::GetMsgStoresTable failed. hr = 0x%08X", hr));
goto Exit;
}
//
// Now we have a pointer to the message store table. Lets find the exchange store.
//
Assert(NULL!=lpStoreTable);
hr = m_lpfnHrQueryAllRows
(
lpStoreTable, // pointer to the table being queried
(LPSPropTagArray)&propStoreProperties, // properties to return in each row
NULL, // no restrictions get the entire table
NULL, // use default sort order
0, // No limit on the number of rows retrieved
&lprowsStores
);
if (FAILED(hr))
{
Error(("HrQueryAllRows on the stores table failed. hr = 0x%08X", hr));
goto Exit;
}
//
// Go over the rows and look for the one with PR_MDB_PROVIDER = pbExchangeProviderPrimaryUserGuid
//
for (ulRow=0;ulRow<lprowsStores->cRows;ulRow++)
{
if ( (sizeof(pbExchangeProviderPrimaryUserGuid)-1 == lprowsStores->aRow[ulRow].lpProps[2].Value.bin.cb))
{
if (!memcmp(lprowsStores->aRow[ulRow].lpProps[2].Value.bin.lpb, pbExchangeProviderPrimaryUserGuid, lprowsStores->aRow[ulRow].lpProps[2].Value.bin.cb))
{
//
// If this is the Exchange store.
// Open the information store using the value of PR_ENTRYID
//
hr = m_lpMapiSession->OpenMsgStore(
NULL,
lprowsStores->aRow[ulRow].lpProps[1].Value.bin.cb,
(LPENTRYID)lprowsStores->aRow[ulRow].lpProps[1].Value.bin.lpb,
NULL, // get the standard interface IMsgStore
MAPI_BEST_ACCESS,
&m_lpIMsgStore);
{
if (FAILED(hr))
{
Error(("OpenMsgStore failed for store [%s]. hr = 0x%08X",
lprowsStores->aRow[ulRow].lpProps[0].Value.lpszA,
hr));
goto Exit;
}
}
}
}
}
Exit:
if (lpStoreTable)
{
lpStoreTable->Release();
lpStoreTable = NULL;
}
if (lprowsStores)
{
FreeProws(lprowsStores);
lprowsStores = NULL;
}
return SUCCEEDED(hr);
}
BOOL
CMAPIabObj::InitMapiService(
HWND hDlg
)
/*++
Routine Description:
Initialize Simple MAPI services
Arguments:
hDlg - Handle to the send fax wizard window
Return Value:
TRUE if successful, FALSE otherwise
NOTE:
Every successful call to this function must be balanced
by a call to DeinitMapiService.
--*/
{
BOOL result = FALSE;
m_lpIMsgStore=NULL;
if(!IsOutlookDefaultClient())
{
return result;
}
//
// Load MAPI32.DLL into memory if necessary
//
if ((m_hInstMapi == NULL) &&
(m_hInstMapi = LoadLibrary(TEXT("MAPI32.DLL"))))
{
//
// Get pointers to various Simple MAPI functions
//
m_lpfnMAPILogonEx = (LPMAPILOGONEX) GetProcAddress(m_hInstMapi, "MAPILogonEx");
m_lpfnMAPILogoff = (LPMAPILOGOFF) GetProcAddress(m_hInstMapi, "MAPILogoff");
m_lpfnMAPIAddress = (LPMAPIADDRESS) GetProcAddress(m_hInstMapi, "MAPIAddress");
m_lpfnMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress(m_hInstMapi, "MAPIFreeBuffer");
m_lpfnMAPIInitialize = (LPMAPIINITIALIZE) GetProcAddress(m_hInstMapi, "MAPIInitialize");
m_lpfnMAPIUninitialize = (LPMAPIUNINITIALIZE) GetProcAddress(m_hInstMapi, "MAPIUninitialize");
m_lpfnMAPIAllocateBuffer = (LPMAPIALLOCATEBUFFER) GetProcAddress(m_hInstMapi, "MAPIAllocateBuffer");
m_lpfnMAPIAllocateMore = (LPMAPIALLOCATEMORE) GetProcAddress(m_hInstMapi, "MAPIAllocateMore");
m_lpfnMAPIAdminProfiles = (LPMAPIADMINPROFILES)GetProcAddress( m_hInstMapi,"MAPIAdminProfiles" );
m_lpfnHrQueryAllRows = (LPHrQueryAllRows)GetProcAddress(m_hInstMapi,"HrQueryAllRows@24");
//
// Begins a simple MAPI session and obtain session handle and pointer
//
if (m_lpfnMAPILogonEx == NULL ||
m_lpfnMAPILogoff == NULL ||
m_lpfnMAPIAddress == NULL ||
m_lpfnMAPIFreeBuffer == NULL ||
m_lpfnMAPIInitialize == NULL ||
m_lpfnMAPIUninitialize == NULL ||
m_lpfnMAPIAllocateBuffer == NULL ||
m_lpfnMAPIAllocateMore == NULL ||
m_lpfnMAPIAdminProfiles == NULL ||
m_lpfnHrQueryAllRows == NULL ||
!DoMapiLogon(hDlg))
{
//
// Clean up properly in case of error
//
m_lpMapiSession = NULL;
FreeLibrary(m_hInstMapi);
m_hInstMapi = NULL;
}
else
{
result = TRUE;
}
}
#ifdef UNICODE
//
// The Outlook Address Book supports Unicode since version 10 (Office XP)
// So we check the version
//
HKEY hRegKey = NULL;
hRegKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, REGKEY_OUTLOOK_CUR_VER, FALSE, KEY_READ);
if(!hRegKey)
{
return result;
}
LPWSTR szCurVer = NULL;
szCurVer = GetRegistryString(hRegKey, TEXT(""), TEXT(""));
RegCloseKey(hRegKey);
if(!szCurVer)
{
return result;
}
//
// The Outlook version string is Outlook.Application.X
// Where is X the version
//
LPWSTR ptr = wcsrchr(szCurVer, TEXT('.'));
if(ptr)
{
ptr = _wcsinc(ptr);
DWORD dwVer = _wtoi(ptr);
if(dwVer >= 10)
{
m_bUnicode = TRUE;
}
}
MemFree (szCurVer);
#endif // UNICODE
return result;
}
VOID
CMAPIabObj::DeinitMapiService(
VOID
)
/*++
Routine Description:
Deinitialize Simple MAPI services if necessary
Arguments:
NONE
Return Value:
NONE
--*/
{
if (m_hInstMapi != NULL)
{
if (m_lpAdrBook)
{
m_lpAdrBook->Release();
m_lpAdrBook = NULL;
}
if (m_lpIMsgStore)
{
m_lpIMsgStore->Release();
m_lpIMsgStore = NULL;
}
if (m_lpMapiSession)
{
m_lpMapiSession->Logoff(0,0,0);
m_lpMapiSession->Release();
m_lpMapiSession = NULL;
}
m_lpfnMAPIUninitialize();
FreeLibrary(m_hInstMapi);
m_hInstMapi = NULL;
}
}
CMAPIabObj::~CMAPIabObj()
/*++
Routine Description:
Destructor for CMAPIabObj class
Arguments:
NONE
Return Value:
NONE
--*/
{
DeinitMapiService();
}
HRESULT
CMAPIabObj::ABAllocateBuffer(
ULONG cbSize,
LPVOID FAR * lppBuffer
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
return m_lpfnMAPIAllocateBuffer( cbSize, lppBuffer );
}
ULONG
CMAPIabObj::ABFreeBuffer(
LPVOID lpBuffer
)
{
return m_lpfnMAPIFreeBuffer(lpBuffer);
}
extern "C"
VOID
FreeMapiEntryID(
PWIZARDUSERMEM pWizardUserMem,
LPENTRYID lpEntryId
)
/*++
Routine Description:
C wrapper for MAPI Free
Arguments:
pWizardUserMem - pointer to WIZARDUSERMEM structure
lpEntryID - pointer to EntryId
Return Value:
NONE
--*/
{
CMAPIabObj * lpCMAPIabObj = (CMAPIabObj *) pWizardUserMem->lpMAPIabInit;
lpCMAPIabObj->ABFreeBuffer(lpEntryId);
}
extern "C"
BOOL
CallMAPIabAddress(
HWND hDlg,
PWIZARDUSERMEM pWizardUserMem,
PRECIPIENT * ppNewRecipient
)
/*++
Routine Description:
C wrapper for CMAPIabObj->Address
Arguments:
hDlg - parent window handle.
pWizardUserMem - pointer to WIZARDUSERMEM structure
ppNewRecipient - list to add new recipients to.
Return Value:
TRUE if all of the entries have a fax number.
FALSE otherwise.
--*/
{
CMAPIabObj * lpCMAPIabObj = (CMAPIabObj *) pWizardUserMem->lpMAPIabInit;
return lpCMAPIabObj->Address(
hDlg,
pWizardUserMem->pRecipients,
ppNewRecipient
);
}
extern "C"
LPTSTR
CallMAPIabAddressEmail(
HWND hDlg,
PWIZARDUSERMEM pWizardUserMem
)
/*++
Routine Description:
C wrapper for CMAPIabObj->AddressEmail
Arguments:
hDlg - parent window handle.
pWizardUserMem - pointer to WIZARDUSERMEM structure
Return Value:
TRUE if found one appropriate E-mail
FALSE otherwise.
--*/
{
CMAPIabObj * lpCMAPIabObj = (CMAPIabObj *) pWizardUserMem->lpMAPIabInit;
return lpCMAPIabObj->AddressEmail(
hDlg
);
}
extern "C"
LPVOID
InitializeMAPIAB(
HINSTANCE hInstance,
HWND hDlg
)
/*++
Routine Description:
Initialize the MAPI.
Arguments:
hInstance - instance handle.
Return Value:
NONE
--*/
{
CMAPIabObj * lpCMAPIabObj = new (std::nothrow) CMAPIabObj ( hInstance, hDlg );
if ((lpCMAPIabObj!=NULL) && (!lpCMAPIabObj->isInitialized())) // constructor failed
{
delete lpCMAPIabObj;
lpCMAPIabObj = NULL;
}
return (LPVOID) lpCMAPIabObj ;
}
extern "C"
VOID
UnInitializeMAPIAB(
LPVOID lpVoid
)
/*++
Routine Description:
UnInitialize the MAPI.
Arguments:
NONE
Return Value:
NONE
--*/
{
CMAPIabObj * lpCMAPIabObj = (CMAPIabObj *) lpVoid;
delete lpCMAPIabObj;
}