#include "StdAfx.h"
#include "winaddrbook.h"
CWinAddrBook::CWinAddrBook(void)
:lpWABObject(NULL),
lpAddrBook(NULL)
, IsInit(false)
{
//Opens the default WAB file in the system and loads it into the object
HINSTANCE hinstWAB=NULL;
HRESULT hr=E_FAIL;
HKEY keyResult;
BYTE keyValue[MAX_PATH];
DWORD dataout=800;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_ALL_ACCESS, &keyResult); //"Software\\Microsoft\\WAB\\DLLPath"
long result = RegQueryValueEx(keyResult, "", 0, 0, keyValue, &dataout);
RegCloseKey(keyResult);
//Get the full path of WAB and store in PathToWAB
strcpy(PathToWAB, (char*)keyValue);
//Now let us load the library
hModule = LoadLibrary(PathToWAB);
}
CWinAddrBook::~CWinAddrBook(void)
{
//Free the library we use to get the WAB file
FreeLibrary(hModule);
IsInit = false;
}
// Initialize the address book and basically open the address book
int CWinAddrBook::InitAddrBook(void)
{
//After opening the library go ahead and try and get the values into memory
//maybe implement a memory map file later depending on how big some on the
//performance of this class after release, and on some people's systems (i.e. huge address files)
//
// For now go ahead and store the information in a STL Vector
if (hModule!=NULL)
{
//We're safe the module was initialzised let's do what we need to do
ssWABOpen = (fWABOpen)GetProcAddress(hModule, "WABOpen");
//If not successful throw an error throw the value = 2
if (ssWABOpen == NULL) return 2;
//It is successful call it
HRESULT hr = (ssWABOpen)(&lpAddrBook, &lpWABObject, NULL, 0);
}
IsInit = true;
LoadEmails(); //Moved here was being weird when called as another function from outsidethe class... hmmmm... go figure?!?
//Everything was OK
return 0;
}
// Load email addresses into the vector
int CWinAddrBook::LoadEmails(void)
{
HRESULT hr = E_FAIL;
if (ssWABOpen==NULL) return 1; //ssWABOpen cannot be NULL
{
ULONG lpcbEntryID;
ENTRYID* lpEntryID;
hr = lpAddrBook->GetPAB(&lpcbEntryID, &lpEntryID);
if (hr!=S_OK) return 10; //error opening the darn PAB
//Declare variables for MAPI and specific access to the PAB
ULONG ulFlags = MAPI_BEST_ACCESS,
ulObjType = NULL;
LPUNKNOWN lpIUnknown = NULL;
hr = lpAddrBook->OpenEntry(lpcbEntryID,
lpEntryID,
NULL,
ulFlags,
&ulObjType,
&lpIUnknown);
ulFlags = NULL; //We are using it again :)
if (ulObjType==MAPI_ABCONT) //See if an address book container was passed which we are looking for
{
IABContainer* lpABContainer = static_cast<IABContainer*>(lpIUnknown); //cast the IUnknown pointer returned from previous function to what we need
LPMAPITABLE lpMAPItbl = NULL;
hr = lpABContainer->GetContentsTable(ulFlags, &lpMAPItbl);
ASSERT(lpMAPItbl);
ULONG ulRows; //Number of rows in the MAPI table (Addresses)
hr = lpMAPItbl->GetRowCount(0, &ulRows);
if (hr!=S_OK) return 11; //Return 11 to tell them we where unable to get the row count
SRowSet* lpRowSet;
hr = lpMAPItbl->QueryRows( //Return all the rows found in the address book
ulRows,
0,
&lpRowSet);
//Grow variable
AddrMemBook.resize(lpRowSet->cRows);
//char Match[200]; strset(Match, 0);
for (ULONG x = 0; x < lpRowSet->cRows; x++)
{
//Loop through all the rows and add it to our address book
//vector variable
EMAILS thisAddr;
SRow* lpRow = &lpRowSet->aRow[x]; //Get this specific row
for (ULONG y = 0; y < lpRow->cValues; y++)
{
//Loop through the fields in the address book and assign
//to our variable and put it in the address book variable
SPropValue* lPropVal = &lpRow->lpProps[y];
switch (lPropVal->ulPropTag)
{
case PR_DISPLAY_NAME_A:
thisAddr.DisplayName = lPropVal->Value.lpszA;
//strcpy(thisAddr->DisplayName, lPropVal->Value.lpszA);
break;
case PR_EMAIL_ADDRESS_A:
thisAddr.EmailAddr = lPropVal->Value.lpszA;
if (strchr(thisAddr.EmailAddr.c_str(), '@')==NULL) //replace with empty string
thisAddr.EmailAddr='\0';
//strcpy(thisAddr->EmailAddr, lPropVal->Value.lpszA);
break;
case PR_NICKNAME_A:
thisAddr.NickName = lPropVal->Value.lpszA;
//strcpy(thisAddr->NickName, lPropVal->Value.lpszA);
break;
default:
break;
}
}//End of cycling through fields
//Add the information to the vector variable
if (!thisAddr.EmailAddr.empty())
AddrMemBook.push_back(thisAddr);
lpWABObject->FreeBuffer(lpRow);
}//End of cycling through rows
lpWABObject->FreeBuffer(lpRowSet);
}
}
return 0;
}
// Test mostly for debug purposes so you can step through and ensure that all the information is present for the address book vector
void CWinAddrBook::TestAddrBook(void)
{
for (int x =0; x < (int)AddrMemBook.size(); x++)
{
//Set break here maybe later do a trace command instead
EMAILS thisAddr = AddrMemBook[x];
TRACE(thisAddr.DisplayName.c_str()); TRACE("\r\n");
TRACE(thisAddr.EmailAddr.c_str()); TRACE("\r\n");
TRACE(thisAddr.NickName.c_str()); TRACE("\r\n");
}
}