#include "StdAfx.h" #include "winaddrbook.h" #include #include #include using namespace std; #include 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, NULL, 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(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"); } } */