#include "wabtest.h" #include #include "resource.h" #include "..\luieng.dll\luieng.h" extern LUIOUT LUIOut; extern BOOL bLUIInit; #ifdef WAB extern LPWABOBJECT lpWABObject; //Global handle to session #endif #ifdef PAB MAPIINIT_0 mapiinit = { MAPI_INIT_VERSION, MAPI_MULTITHREAD_NOTIFICATIONS }; #endif //PAB PropTableEntry PropTable[] = { PR_7BIT_DISPLAY_NAME, "PR_7BIT_DISPLAY_NAME", 0, PR_ACCOUNT, "PR_ACCOUNT", 0, PR_ADDRTYPE, "PR_ADDRTYPE", 0, PR_ALTERNATE_RECIPIENT, "PR_ALTERNATE_RECIPIENT", 0, PR_ASSISTANT, "PR_ASSISTANT", 0, PR_ASSISTANT_TELEPHONE_NUMBER, "PR_ASSISTANT_TELEPHONE_NUMBER", 0, PR_BEEPER_TELEPHONE_NUMBER, "PR_BEEPER_TELEPHONE_NUMBER", 0, PR_BIRTHDAY, "PR_BIRTHDAY", 0, PR_BUSINESS_ADDRESS_CITY, "PR_BUSINESS_ADDRESS_CITY", 0, PR_BUSINESS_ADDRESS_COUNTRY, "PR_BUSINESS_ADDRESS_COUNTRY", 0, PR_BUSINESS_ADDRESS_POST_OFFICE_BOX, "PR_BUSINESS_ADDRESS_POST_OFFICE_BOX", 0, PR_BUSINESS_ADDRESS_POSTAL_CODE, "PR_BUSINESS_ADDRESS_POSTAL_CODE", 0, PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE, "PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE", 0, PR_BUSINESS_ADDRESS_STREET, "PR_BUSINESS_ADDRESS_STREET", 0, PR_BUSINESS_FAX_NUMBER, "PR_BUSINESS_FAX_NUMBER", 0, PR_BUSINESS_HOME_PAGE, "PR_BUSINESS_HOME_PAGE", 0, PR_BUSINESS_TELEPHONE_NUMBER, "PR_BUSINESS_TELEPHONE_NUMBER", 0, PR_BUSINESS2_TELEPHONE_NUMBER, "PR_BUSINESS2_TELEPHONE_NUMBER", 0, PR_CALLBACK_TELEPHONE_NUMBER, "PR_CALLBACK_TELEPHONE_NUMBER", 0, PR_CAR_TELEPHONE_NUMBER, "PR_CAR_TELEPHONE_NUMBER", 0, PR_CELLULAR_TELEPHONE_NUMBER, "PR_CELLULAR_TELEPHONE_NUMBER", 0, PR_CHILDRENS_NAMES, "PR_CHILDRENS_NAMES", 0, PR_COMMENT, "PR_COMMENT", 0, PR_COMPANY_MAIN_PHONE_NUMBER, "PR_COMPANY_MAIN_PHONE_NUMBER", 0, PR_COMPANY_NAME, "PR_COMPANY_NAME", 0, PR_COMPUTER_NETWORK_NAME, "PR_COMPUTER_NETWORK_NAME", 0, PR_CONTACT_ADDRTYPES, "PR_CONTACT_ADDRTYPES", 0, PR_CONTACT_DEFAULT_ADDRESS_INDEX, "PR_CONTACT_DEFAULT_ADDRESS_INDEX", 0, PR_CONTACT_EMAIL_ADDRESSES, "PR_CONTACT_EMAIL_ADDRESSES", 0, PR_CONTACT_ENTRYIDS, "PR_CONTACT_ENTRYIDS", 0, PR_CONTACT_VERSION, "PR_CONTACT_VERSION", 0, PR_CONVERSION_PROHIBITED, "PR_CONVERSION_PROHIBITED", 0, PR_COUNTRY, "PR_COUNTRY", 0, PR_CUSTOMER_ID, "PR_CUSTOMER_ID", 0, PR_DEPARTMENT_NAME, "PR_DEPARTMENT_NAME", 0, PR_DISCLOSE_RECIPIENTS, "PR_DISCLOSE_RECIPIENTS", 0, PR_DISPLAY_NAME, "PR_DISPLAY_NAME", 0, PR_DISPLAY_NAME_PREFIX, "PR_DISPLAY_NAME_PREFIX", 0, PR_EMAIL_ADDRESS, "PR_EMAIL_ADDRESS", 0, PR_ENTRYID, "PR_ENTRYID", 0, PR_FTP_SITE, "PR_FTP_SITE", 0, PR_GENDER, "PR_GENDER", 0, PR_GENERATION, "PR_GENERATION", 0, PR_GIVEN_NAME, "PR_GIVEN_NAME", 0, PR_GOVERNMENT_ID_NUMBER, "PR_GOVERNMENT_ID_NUMBER", 0, PR_HOBBIES, "PR_HOBBIES", 0, PR_HOME_ADDRESS_CITY, "PR_HOME_ADDRESS_CITY", 0, PR_HOME_ADDRESS_COUNTRY, "PR_HOME_ADDRESS_COUNTRY", 0, PR_HOME_ADDRESS_POST_OFFICE_BOX, "PR_HOME_ADDRESS_POST_OFFICE_BOX", 0, PR_HOME_ADDRESS_POSTAL_CODE, "PR_HOME_ADDRESS_POSTAL_CODE", 0, PR_HOME_ADDRESS_STATE_OR_PROVINCE, "PR_HOME_ADDRESS_STATE_OR_PROVINCE", 0, PR_HOME_ADDRESS_STREET, "PR_HOME_ADDRESS_STREET", 0, PR_HOME_FAX_NUMBER, "PR_HOME_FAX_NUMBER", 0, PR_HOME_TELEPHONE_NUMBER, "PR_HOME_TELEPHONE_NUMBER", 0, PR_HOME2_TELEPHONE_NUMBER, "PR_HOME2_TELEPHONE_NUMBER", 0, PR_INITIALS, "PR_INITIALS", 0, PR_ISDN_NUMBER, "PR_ISDN_NUMBER", 0, PR_KEYWORD, "PR_KEYWORD", 0, PR_LANGUAGE, "PR_LANGUAGE", 0, PR_LOCALITY, "PR_LOCALITY", 0, PR_LOCATION, "PR_LOCATION", 0, PR_MAIL_PERMISSION, "PR_MAIL_PERMISSION", 0, PR_MANAGER_NAME, "PR_MANAGER_NAME", 0, PR_MHS_COMMON_NAME, "PR_MHS_COMMON_NAME", 0, PR_MIDDLE_NAME, "PR_MIDDLE_NAME", 0, PR_MOBILE_TELEPHONE_NUMBER, "PR_MOBILE_TELEPHONE_NUMBER", 0, PR_NICKNAME, "PR_NICKNAME", 0, PR_OBJECT_TYPE, "PR_OBJECT_TYPE", 0, PR_OFFICE_LOCATION, "PR_OFFICE_LOCATION", 0, PR_OFFICE_TELEPHONE_NUMBER, "PR_OFFICE_TELEPHONE_NUMBER", 0, PR_OFFICE2_TELEPHONE_NUMBER, "PR_OFFICE2_TELEPHONE_NUMBER", 0, PR_ORGANIZATIONAL_ID_NUMBER, "PR_ORGANIZATIONAL_ID_NUMBER", 0, PR_ORIGINAL_DISPLAY_NAME, "PR_ORIGINAL_DISPLAY_NAME", 0, PR_ORIGINAL_ENTRYID, "PR_ORIGINAL_ENTRYID", 0, PR_ORIGINAL_SEARCH_KEY, "PR_ORIGINAL_SEARCH_KEY", 0, PR_OTHER_ADDRESS_CITY, "PR_OTHER_ADDRESS_CITY", 0, PR_OTHER_ADDRESS_COUNTRY, "PR_OTHER_ADDRESS_COUNTRY", 0, PR_OTHER_ADDRESS_POST_OFFICE_BOX, "PR_OTHER_ADDRESS_POST_OFFICE_BOX", 0, PR_OTHER_ADDRESS_POSTAL_CODE, "PR_OTHER_ADDRESS_POSTAL_CODE", 0, PR_OTHER_ADDRESS_STATE_OR_PROVINCE, "PR_OTHER_ADDRESS_STATE_OR_PROVINCE", 0, PR_OTHER_ADDRESS_STREET,"PR_OTHER_ADDRESS_STREET", 0, PR_OTHER_TELEPHONE_NUMBER, "PR_OTHER_TELEPHONE_NUMBER", 0, PR_PAGER_TELEPHONE_NUMBER, "PR_PAGER_TELEPHONE_NUMBER", 0, PR_PERSONAL_HOME_PAGE, "PR_PERSONAL_HOME_PAGE", 0, PR_POST_OFFICE_BOX, "PR_POST_OFFICE_BOX", 0, PR_POSTAL_ADDRESS, "PR_POSTAL_ADDRESS", 0, PR_POSTAL_CODE, "PR_POSTAL_CODE", 0, PR_PREFERRED_BY_NAME, "PR_PREFERRED_BY_NAME", 0, PR_PRIMARY_FAX_NUMBER, "PR_PRIMARY_FAX_NUMBER", 0, PR_PRIMARY_TELEPHONE_NUMBER, "PR_PRIMARY_TELEPHONE_NUMBER", 0, PR_PROFESSION, "PR_PROFESSION", 0, PR_RADIO_TELEPHONE_NUMBER, "PR_RADIO_TELEPHONE_NUMBER", 0, PR_SEND_RICH_INFO, "PR_SEND_RICH_INFO", 0, PR_SPOUSE_NAME, "PR_SPOUSE_NAME", 0, PR_STATE_OR_PROVINCE, "PR_STATE_OR_PROVINCE", 0, PR_STREET_ADDRESS, "PR_STREET_ADDRESS", 0, PR_SURNAME, "PR_SURNAME", 0, PR_TELEX_NUMBER, "PR_TELEX_NUMBER", 0, PR_TITLE, "PR_TITLE", 0, PR_TRANSMITABLE_DISPLAY_NAME, "PR_TRANSMITABLE_DISPLAY_NAME", 0, PR_TTYTDD_PHONE_NUMBER, "PR_TTYTDD_PHONE_NUMBER", 0, PR_USER_CERTIFICATE, "PR_USER_CERTIFICATE", 0, PR_WEDDING_ANNIVERSARY, "PR_WEDDING_ANNIVERSARY", 0, PR_USER_X509_CERTIFICATE, "PR_USER_X509_CERTIFICATE", 0, (ULONG)0, "End of Table", 0 }; HRESULT OpenPABID( IN LPADRBOOK lpAdrBook, OUT ULONG *lpcbEidPAB, OUT LPENTRYID *lppEidPAB, OUT LPABCONT *lppPABCont, OUT ULONG *lpulObjType) { HRESULT hr = hrSuccess; int retval = TRUE; *lpulObjType = 0; if ( (NULL == lpcbEidPAB) || (NULL == lppEidPAB) || (NULL == lppPABCont) ) return(FALSE); *lpcbEidPAB = 0; *lppEidPAB = NULL; *lppPABCont = NULL; // // Get the PAB // hr = lpAdrBook->GetPAB( OUT lpcbEidPAB, OUT lppEidPAB); if (HR_FAILED(hr)) { retval = FALSE; goto out; } if (0 == *lpcbEidPAB) //There is no PAB associated with this profile { LUIOut(L2, "Call to GetPAB FAILED. No PAB associated with this profile"); retval = FALSE; goto out; } // // Open the PAB Container // hr = lpAdrBook->OpenEntry( IN *lpcbEidPAB, IN *lppEidPAB, IN NULL, //interface IN MAPI_MODIFY, //flags OUT lpulObjType, OUT (LPUNKNOWN *) lppPABCont); if (0 == *lpulObjType) { retval = FALSE; goto out; } out: return(retval); } #ifdef PAB BOOL MapiInitLogon(OUT LPMAPISESSION * lppMAPISession) { HRESULT hr = hrSuccess; SCODE sc = SUCCESS_SUCCESS; int retval=TRUE; char szProfileName[SML_BUF]; hr = MAPIInitialize(IN & mapiinit); if (hr) { if (FAILED (GetScode(hr))) { LUIOut(L1,"Could not initialize MAPI\n"); retval=FALSE; } } szProfileName[0]='\0'; GetPrivateProfileString("Misc","Profile","",szProfileName,SML_BUF,"c:\\pabtests.ini"); sc = MAPILogonEx( IN 0, //window handle IN szProfileName, //Profile Name IN NULL, //Password IN MAPI_NEW_SESSION | MAPI_EXTENDED | MAPI_LOGON_UI | MAPI_EXPLICIT_PROFILE | MAPI_ALLOW_OTHERS | MAPI_NO_MAIL, //Flags OUT lppMAPISession); //Session Pointer address if (FAILED(sc)) { hr = ResultFromScode(sc); LUIOut(L1,"Could not start MAPI Session"); retval=FALSE; } return retval; } #endif //PAB BOOL GetPropsFromIniBufEntry(LPSTR EntryBuf,ULONG cValues, char (*EntProp)[BIG_BUF]) { //char szTemp[BIG_BUF]; int j=0; if (EntryBuf) { for (int i = 0; i < (int)cValues; i++) { if ((*EntryBuf) == '"') { EntryBuf++; } j=0; while ((*EntryBuf)&&((*EntryBuf) != '"')&&(j< BIG_BUF-1)) { EntProp[i][j]= *EntryBuf; j++; EntryBuf++; } EntProp[i][j]='\0'; if (*EntryBuf) EntryBuf++; if ((*EntryBuf)&&((*EntryBuf) == ',')) EntryBuf++; } return TRUE; } else { for (int i = 0; i < (int)cValues; i++) { EntProp[i][0]=0; } return FALSE; } } HRESULT HrCreateEntryListFromID( IN LPWABOBJECT lpLocalWABObject, IN ULONG cbeid, // count of bytes in Entry ID IN LPENTRYID lpeid, // pointer to Entry ID OUT LPENTRYLIST FAR *lppEntryList) // pointer to address variable of Entry // list { HRESULT hr = NOERROR; SCODE sc = 0; LPVOID lpvSBinaryArray = NULL; LPVOID lpvSBinary = NULL; LPVOID lpv = NULL; if (NULL == lppEntryList) return(FALSE); *lppEntryList = NULL; #ifdef PAB sc = MAPIAllocateBuffer(cbeid, &lpv); #endif #ifdef WAB sc = lpLocalWABObject->AllocateBuffer(cbeid, &lpv); #endif if(FAILED(sc)) { hr = ResultFromScode(sc); goto cleanup; } // Copy entry ID CopyMemory(lpv, lpeid, cbeid); #ifdef PAB sc = MAPIAllocateBuffer(sizeof(SBinary), &lpvSBinary); #endif #ifdef WAB sc = lpLocalWABObject->AllocateBuffer(sizeof(SBinary), &lpvSBinary); #endif if(FAILED(sc)) { hr = ResultFromScode(sc); goto cleanup; } // Initialize SBinary structure ZeroMemory(lpvSBinary, sizeof(SBinary)); ((LPSBinary)lpvSBinary)->cb = cbeid; ((LPSBinary)lpvSBinary)->lpb = (LPBYTE)lpv; #ifdef PAB sc = MAPIAllocateBuffer(sizeof(SBinaryArray), &lpvSBinaryArray); #endif #ifdef WAB sc = lpLocalWABObject->AllocateBuffer(sizeof(SBinaryArray), &lpvSBinaryArray); #endif if(FAILED(sc)) { hr = ResultFromScode(sc); goto cleanup; } // Initialize SBinaryArray structure ZeroMemory(lpvSBinaryArray, sizeof(SBinaryArray)); ((SBinaryArray *)lpvSBinaryArray)->cValues = 1; ((SBinaryArray *)lpvSBinaryArray)->lpbin = (LPSBinary)lpvSBinary; *lppEntryList = (LPENTRYLIST)lpvSBinaryArray; cleanup: if (HR_FAILED(hr)) { #ifdef PAB if (lpv) MAPIFreeBuffer(lpv); if (lpvSBinary) MAPIFreeBuffer(lpvSBinary); if (lpvSBinaryArray) MAPIFreeBuffer(lpvSBinaryArray); #endif #ifdef WAB if (lpv) lpLocalWABObject->FreeBuffer(lpv); if (lpvSBinary) lpLocalWABObject->FreeBuffer(lpvSBinary); if (lpvSBinaryArray) lpLocalWABObject->FreeBuffer(lpvSBinaryArray); #endif } return(hr); } HRESULT HrCreateEntryListFromRows( IN LPWABOBJECT lpLocalWABObject, IN LPSRowSet far* lppRows, OUT LPENTRYLIST FAR *lppEntryList) // pointer to address variable of Entry // list { LPSRowSet lpRows = *lppRows; HRESULT hr = NOERROR; SCODE sc = 0; SBinaryArray* lpvSBinaryArray = NULL; ULONG Rows = lpRows->cRows; unsigned int PropIndex; ULONG cb; LPENTRYID lpb; if (NULL == lppEntryList) return(FALSE); *lppEntryList = NULL; if (lpRows) { // Allocate the SBinaryArray sc = lpLocalWABObject->AllocateBuffer(sizeof(SBinaryArray), (void**)&lpvSBinaryArray); if(FAILED(sc)) { LUIOut(L2, "HrCreateEntryListFromRows: Unable to allocate memory for the SBinaryArray."); hr = ResultFromScode(sc); goto cleanup; } // Initialize SBinaryArray structure ZeroMemory(lpvSBinaryArray, sizeof(SBinaryArray)); lpvSBinaryArray->cValues = Rows; // Allocate the SBinary structures sc = lpLocalWABObject->AllocateBuffer((Rows*sizeof(SBinary)), (void**)&lpvSBinaryArray->lpbin); if(FAILED(sc)) { LUIOut(L2, "HrCreateEntryListFromRows: Unable to allocate memory for the SBinary structures."); hr = ResultFromScode(sc); goto cleanup; } // Initialize SBinary structure ZeroMemory(lpvSBinaryArray->lpbin, (Rows*sizeof(SBinary))); FindPropinRow(&lpRows->aRow[0], // Find which column has the EID PR_ENTRYID, &PropIndex); // Walk through the rows, allocate the lpb and copy over each cbeid and lpb into the entrylist for (ULONG Row = 0; Row < Rows; Row++) { cb = lpRows->aRow[Row].lpProps[PropIndex].Value.bin.cb, lpb = (ENTRYID*)lpRows->aRow[Row].lpProps[PropIndex].Value.bin.lpb, sc = lpLocalWABObject->AllocateBuffer(cb, (void**)&(lpvSBinaryArray->lpbin[Row].lpb)); if(FAILED(sc)) { LUIOut(L2, "HrCreateEntryListFromRows: Unable to allocate memory for the SBinary->lpb."); hr = ResultFromScode(sc); goto cleanup; } // Copy entry ID lpvSBinaryArray->lpbin[Row].cb = cb; CopyMemory(lpvSBinaryArray->lpbin[Row].lpb, lpb, cb); } *lppEntryList = (LPENTRYLIST)lpvSBinaryArray; return TRUE; } return FALSE; cleanup: if (HR_FAILED(hr)) { for (ULONG Kill=0; Killlpbin[Kill].lpb) lpLocalWABObject->FreeBuffer(lpvSBinaryArray->lpbin[Kill].lpb); lpvSBinaryArray->lpbin[Kill].lpb = NULL; } if (lpvSBinaryArray->lpbin) lpLocalWABObject->FreeBuffer(lpvSBinaryArray->lpbin); if (lpvSBinaryArray) lpLocalWABObject->FreeBuffer(lpvSBinaryArray); } return(hr); } BOOL FreeEntryList(IN LPWABOBJECT lpLocalWABObject, IN LPENTRYLIST *lppEntryList) // pointer to address variable of Entry // list { LPENTRYLIST lpEntryList = *lppEntryList; if (lpEntryList == NULL) return FALSE; for (ULONG Row = 0; Row < lpEntryList->cValues; Row++) { if (lpEntryList->lpbin[Row].lpb) lpLocalWABObject->FreeBuffer(lpEntryList->lpbin[Row].lpb); } if (lpEntryList->lpbin) lpLocalWABObject->FreeBuffer(lpEntryList->lpbin); if (lpEntryList) lpLocalWABObject->FreeBuffer(lpEntryList); *lppEntryList = NULL; return TRUE; } BOOL FreeRows(IN LPWABOBJECT lpLocalWABObject, IN LPSRowSet far* lppRows) { LPSRowSet lpRows = *lppRows; #ifdef WAB if (lpRows) { for (ULONG Kill = 0; Kill < lpRows->cRows; Kill++) lpLocalWABObject->FreeBuffer(lpRows->aRow[Kill].lpProps); lpLocalWABObject->FreeBuffer(lpRows); *lppRows = NULL; #endif return TRUE; } return FALSE; } BOOL DisplayRows(IN LPSRowSet lpRows) { ULONG Rows, Columns; WORD* Key; if (lpRows) { Rows = lpRows->cRows; LUIOut(L2, "%u rows found.", Rows); for (ULONG Row = 0; Row < Rows; Row++) { Columns = lpRows->aRow[Row].cValues; LUIOut(L3, "Row %u contains %u columns.", Row, Columns); for (ULONG Column = 0; Column < Columns; Column++) { switch(lpRows->aRow[Row].lpProps[Column].ulPropTag) { case PR_ADDRTYPE: LUIOut(L3, "Column %u: PR_ADDRTYPE = %s", Column, lpRows->aRow[Row].lpProps[Column].Value.LPSZ); break; case PR_DISPLAY_NAME: LUIOut(L3, "Column %u: PR_DISPLAY_NAME = %s", Column, lpRows->aRow[Row].lpProps[Column].Value.LPSZ); break; case PR_DISPLAY_TYPE: switch(lpRows->aRow[Row].lpProps[Column].Value.l) { case DT_AGENT: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_AGENT", Column); break; case DT_DISTLIST: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_DISTLIST", Column); break; case DT_FORUM: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_FORUM", Column); break; case DT_MAILUSER: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_MAILUSER", Column); break; case DT_ORGANIZATION: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_ORGANIZATION", Column); break; case DT_PRIVATE_DISTLIST: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_PRIVATE_DISTLIST", Column); break; case DT_REMOTE_MAILUSER: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_REMOTE_MAILUSER", Column); break; default: LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = UNKNOWN!! [0x%x]", Column, lpRows->aRow[Row].lpProps[Column].Value.l); } break; case PR_ENTRYID: LUIOut(L3, "Column %u: PR_ENTRYID", Column); break; case PR_INSTANCE_KEY: Key = (WORD*)lpRows->aRow[Row].lpProps[Column].Value.bin.lpb; LUIOut(L3, "Column %u: PR_INSTANCE_KEY = 0x%x%x%x%x%x%x%x%x", Column, Key[0],Key[2],Key[4],Key[6],Key[8],Key[10],Key[12],Key[14]); break; case PR_OBJECT_TYPE: switch(lpRows->aRow[Row].lpProps[Column].Value.l) { case MAPI_ABCONT: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_ABCONT", Column); break; case MAPI_ADDRBOOK: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_ADDRBOOK", Column); break; case MAPI_ATTACH: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_ATTACH", Column); break; case MAPI_DISTLIST: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_DISTLIST", Column); break; case MAPI_FOLDER: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_FOLDER", Column); break; case MAPI_FORMINFO: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_FORMINFO", Column); break; case MAPI_MAILUSER: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_MAILUSER", Column); break; case MAPI_MESSAGE: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_MESSAGE", Column); break; case MAPI_PROFSECT: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_PROFSECT", Column); break; case MAPI_STATUS: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_STATUS", Column); break; case MAPI_STORE: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_STORE", Column); break; default: LUIOut(L3, "Column %u: PR_OBJECT_TYPE = UNKNOWN!! [0x%x]", Column, lpRows->aRow[Row].lpProps[Column].Value.l); } break; case PR_RECORD_KEY: LUIOut(L3, "Column %u: PR_RECORD_KEY", Column); break; default: LUIOut(L3, "Column %u: Property tag UNKNOWN!! [0x%x]", Column, lpRows->aRow[Row].lpProps[Column].ulPropTag); } } } return TRUE; } return FALSE; } BOOL ValidateAdrList(LPADRLIST lpAdrList, ULONG cEntries) { int i = 0; int idx = 0; int cMaxProps = 0; for(i=0; i<(int) cEntries; ++i) { cMaxProps = (int)lpAdrList->aEntries[i].cValues; //Check to see if Email Address Type exists idx=0; while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ADDRTYPE ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_ADDRTYPE was not found in the lpAdrList"); return FALSE; } } //Check to see if Email Address exists idx=0; while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_OBJECT_TYPE ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_OBJECT_TYPE was not found in the lpAdrList"); return FALSE; } } //Check to see if Email Address exists idx=0; while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_TYPE ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_DISPLAY_TYPE was not found in the lpAdrList"); return FALSE; } } //Check to see if Display Name exists idx=0; while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_NAME ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_DISPLAY_NAME was not found in the lpAdrList"); return FALSE; } } LUIOut(L4,"Display Name: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); //Check to see if EntryID exists idx=0; while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ENTRYID ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_ENTRYID was not found in the lpAdrList"); return FALSE; } } } return TRUE; } // // PROCEDURE: VerifyResolvedAdrList // DESCRIPTION: Walk through a lpAdrList looking for PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, // PR_ADDRTYPE, PR_ENTRYID, and PR_OBJECT_TYPE. Each EID is sanity checked // (lpb != NULL and cb != 0) and valid EIDs are passed to OpenEntry with // a MailUser interface specified. If OpenEntry succedes, we assume the EID // is a valid MailUser ID. // // PARAMETERS: LPADRLIST lpAdrList // char* lpszInput - can be NULL to bypass match checking // BOOL VerifyResolvedAdrList(LPADRLIST lpAdrList, char* lpszInput) { extern LPADRBOOK glbllpAdrBook; int i = 0, idx = 0, cMaxProps = 0; BOOL Found = FALSE, retval = TRUE, localretval = TRUE; ULONG cEntries = lpAdrList->cEntries; ULONG cbLookupEID, ulObjType; LPENTRYID lpLookupEID; HRESULT hr; LPUNKNOWN lpUnk=NULL; LPADRBOOK lpAdrBook; LPCIID lpcIID; LPVOID Reserved1=NULL; DWORD Reserved2=0; // LPWABOBJECT lpWABObject2; /* kludge to work around multiple wabopen/release bug, storing adrbook ptr in a global variable hr = WABOpen(&lpAdrBook, &lpWABObject2, Reserved1, Reserved2); if (hr != S_OK) { LUIOut(L4, "WABOpen FAILED. Couldn't obtain IAdrBook."); retval = FALSE; } */ #ifdef WAB lpAdrBook = glbllpAdrBook; lpAdrBook->AddRef(); #endif //WAB // Walk through each AdrList entry for(i=0; ((i<(int) lpAdrList->cEntries) && (!Found)); ++i) { LUIOut(L3, "Searching Entry #%i out of %i", i+1, cEntries); cMaxProps = (int)lpAdrList->aEntries[i].cValues; //Check to see if Display Name exists idx=0; localretval = TRUE; while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_NAME ) && localretval) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_DISPLAY_NAME was not found in lpAdrList entry #%i",i); localretval = FALSE; retval = FALSE; goto skip; } } LUIOut(L4,"Display Name: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); if (lpszInput) { if (!lstrcmp(lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ,lpszInput)) { LUIOut(L3, "Found the entry we just added"); Found = TRUE; } else { LUIOut(L3, "Did not find the entry we just added"); retval = FALSE; } } //Check to see if EntryID exists LUIOut(L3, "Verifying a PR_ENTRYID entry exists in the PropertyTagArray"); idx=0; localretval = TRUE; while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ENTRYID ) && localretval) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_ENTRYID was not found in the lpAdrList"); localretval = FALSE; retval = FALSE; goto skip; } } if (idx < cMaxProps) { // Store EID for call to OpenEntry lpLookupEID = (ENTRYID*)lpAdrList->aEntries[i].rgPropVals[idx].Value.bin.lpb; cbLookupEID = lpAdrList->aEntries[i].rgPropVals[idx].Value.bin.cb; if ((cbLookupEID == 0) || (lpLookupEID == NULL)) { LUIOut(L4, "EntryID found, but is NULL or has size = 0. Test FAILED"); retval = FALSE; goto skip; } else LUIOut(L4, "EntryID found and appears to be valid (not NULL and >0 size)."); // Try calling OpenEntry on the returned EID specifying a mailuser interface LUIOut(L4, "Calling OpenEntry on the EntryID"); lpcIID = &IID_IMailUser; hr = lpAdrBook->OpenEntry(cbLookupEID, lpLookupEID, lpcIID, MAPI_BEST_ACCESS, &ulObjType, &lpUnk); switch(hr) { case S_OK: if ((lpUnk) && (ulObjType==MAPI_MAILUSER)) LUIOut(L4, "OpenEntry call succeded on this EntryID and returned a valid object pointer and type."); else { LUIOut(L4, "OpenEntry call succeded on this EntryID but returned an invalid object pointer or incorrect type. Test FAILED"); retval = FALSE; } break; case MAPI_E_NOT_FOUND: LUIOut(L4, "OpenEntry returned MAPI_E_NOT_FOUND for this EntryID. Test FAILED"); retval = FALSE; break; case MAPI_E_UNKNOWN_ENTRYID: LUIOut(L4, "OpenEntry returned MAPI_E_UNKNOWN_ENTRYID for this EntryID. Test FAILED"); retval = FALSE; break; case MAPI_E_NO_ACCESS: LUIOut(L4, "OpenEntry returned MAPI_E_NO_ACCESS for this EntryID. Test FAILED"); retval = FALSE; break; default: LUIOut(L4, "OpenEntry returned unknown result code (0x%x) for this EntryID. Test FAILED", hr); retval = FALSE; lpUnk = NULL; break; } } //Check to see if PR_EMAIL_ADDRESS exists LUIOut(L3, "Verifying a PR_EMAIL_ADDRESS entry exists in the PropertyTagArray"); idx=0; localretval = TRUE; while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_EMAIL_ADDRESS ) && localretval) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_EMAIL_ADDRESS was not found in the lpAdrList"); localretval = FALSE; //retval = FALSE; } } if (idx < cMaxProps) { LUIOut(L4,"Email Address: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); } //Check to see if PR_ADDRTYPE exists LUIOut(L3, "Verifying a PR_ADDRTYPE entry exists in the PropertyTagArray"); idx=0; localretval = TRUE; while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ADDRTYPE ) && localretval) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_ADDRTYPE was not found in the lpAdrList"); localretval = FALSE; //retval = FALSE; } } if (idx < cMaxProps) { LUIOut(L4,"Address Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); } //Check to see if PR_OBJECT_TYPE exists LUIOut(L3, "Verifying a PR_OBJECT_TYPE entry exists in the PropertyTagArray"); idx=0; localretval = TRUE; while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_OBJECT_TYPE ) && localretval) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_OBJECT_TYPE was not found in the lpAdrList"); localretval = FALSE; retval = FALSE; } } if (idx < cMaxProps) { switch (lpAdrList->aEntries[i].rgPropVals[idx].Value.l) { case MAPI_MAILUSER: LUIOut(L4, "Object Type: MAPI_MAILUSER"); break; case MAPI_DISTLIST: LUIOut(L4, "Object Type: MAPI_DISTLIST"); break; default: LUIOut(L4,"Object Type not MAILUSER or DISTLIST. Test FAILED"); } } skip: // skip the current entry and continue through the lpAdrList if (lpUnk) lpUnk->Release(); //Release the object returned from OpenEntry } if (lpAdrBook) lpAdrBook->Release(); //if (lpWABObject2) lpWABObject->Release(); return(retval); } BOOL DisplayAdrList(LPADRLIST lpAdrList, ULONG cEntries) { int i = 0; int idx = 0; int cMaxProps = 0; BOOL Found, retval = TRUE; for(i=0; i<(int) cEntries; ++i) { LUIOut(L3, "Searching Entry #%i out of %i", i+1, cEntries); cMaxProps = (int)lpAdrList->aEntries[i].cValues; /* //Check to see if Email Address Type exists idx=0; Found = TRUE; while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ADDRTYPE ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_ADDRTYPE was not found in the lpAdrList"); Found = FALSE; } } if (Found) LUIOut(L4,"Address Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); //Check to see if Email Address exists idx=0; Found = TRUE; while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_OBJECT_TYPE ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_OBJECT_TYPE was not found in the lpAdrList"); Found = FALSE; } } if (Found) LUIOut(L4,"Object Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); //Check to see if display type exists idx=0; Found = TRUE; while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_TYPE ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_DISPLAY_TYPE was not found in the lpAdrList"); Found = FALSE; } } if (Found) LUIOut(L4,"Display Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); */ //Check to see if Display Name exists idx=0; Found = TRUE; while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_NAME ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_DISPLAY_NAME was not found in the lpAdrList"); Found = FALSE; } } if (Found) LUIOut(L4,"Display Name: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ); //Check to see if EntryID exists idx=0; Found = TRUE; while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ENTRYID ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_ENTRYID was not found in the lpAdrList"); Found = FALSE; } } if (Found) LUIOut(L4,"Entry ID Found"); //Check to see if Recipient Type exists idx=0; Found = TRUE; while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_RECIPIENT_TYPE ) { idx++; if(idx == cMaxProps) { LUIOut(L4, "PR_RECIPIENT_TYPE was not found in the lpAdrList"); Found = FALSE; } } if (Found) { switch((ULONG)lpAdrList->aEntries[i].rgPropVals[idx].Value.l) { case MAPI_TO: { LUIOut(L4, "Recipient Type: [TO:]"); break; } case MAPI_CC: { LUIOut(L4, "Recipient Type: [CC:]"); break; } case MAPI_BCC: { LUIOut(L4, "Recipient Type: [BCC:]"); break; } default: { LUIOut(L4, "Recipient Type: [UNKNOWN]. Test FAILED"); } } } } return retval; } BOOL LogIt(HRESULT hr, int Level,char * LogString) { switch (Level) { case 0: if (HR_FAILED(hr)) { LUIOut(LFAIL, "%s",LogString); return FALSE; } else LUIOut(LPASS,"%s",LogString); return TRUE; case 1: if (HR_FAILED(hr)) { LUIOut(LFAIL1, "%s",LogString); return FALSE; } else LUIOut(LPASS1,"%s",LogString); return TRUE; case 2: if (HR_FAILED(hr)) { LUIOut(LFAIL2, "%s",LogString); return FALSE; } else LUIOut(LPASS2,"%s",LogString); return TRUE; case 3: if (HR_FAILED(hr)) { LUIOut(LFAIL3, "%s",LogString); return FALSE; } else LUIOut(LPASS3,"%s",LogString); return TRUE; case 4: if (HR_FAILED(hr)) { LUIOut(LFAIL4, "%s",LogString); return FALSE; } else LUIOut(LPASS4,"%s",LogString); return TRUE; default: break; } if (HR_FAILED(hr)) { LUIOut(LFAIL2, "%s",LogString); return FALSE; } else LUIOut(LPASS2,"%s",LogString); return TRUE; } // // PROCEDURE: AllocateAdrList // DESCRIPTION: Uses either MAPI or WAB allocaters to allocate an lpAdrList // // PARAMETERS: LPWABOBJECT lpLocalWABObject - ptr to opened WABObject // int nEntries - how many AdrEntries to allocate // int nProps - how many properties per AdrEntry // LPADRLIST * lppAdrList - where to return the allocated ptr // BOOL AllocateAdrList(IN LPWABOBJECT lpLocalWABObject, IN int nEntries, IN int nProps, OUT LPADRLIST * lppAdrList) { BOOL retval = TRUE; SCODE sc; *lppAdrList = NULL; #ifdef PAB if (! (sc = MAPIAllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)), (void **)lppAdrList))) { (*lppAdrList)->cEntries = nEntries; for (int entry = 0; entry < nEntries; entry++) { (*lppAdrList)->aEntries[entry].ulReserved1 = 0; (*lppAdrList)->aEntries[entry].cValues = nProps; sc = MAPIAllocateBuffer((nProps * sizeof(SPropValue)), (void **)(&(*lppAdrList)->aEntries[entry].rgPropVals)); if (sc != S_OK) retval = FALSE; } } else retval = FALSE; // // Should do cleanup here for a partial allocation that fails // #endif //PAB #ifdef WAB if (! (sc = lpLocalWABObject->AllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)), (void **)lppAdrList))) { (*lppAdrList)->cEntries = nEntries; for (int entry = 0; entry < nEntries; entry++) { (*lppAdrList)->aEntries[entry].ulReserved1 = 0; (*lppAdrList)->aEntries[entry].cValues = nProps; sc = lpLocalWABObject->AllocateBuffer((nProps * sizeof(SPropValue)), (void **)(&(*lppAdrList)->aEntries[entry].rgPropVals)); if (sc != S_OK) retval = FALSE; } } else retval = FALSE; // // Should do cleanup here for a partial allocation that fails // #endif //WAB return retval; } // // PROCEDURE: GrowAdrList // DESCRIPTION: Takes an existing lpAdrList, allocates a new, larger lpAdrList // , copies over the old entries and allocates new entries, returning // a pointer to the new AdrList in lpAdrList. // // PARAMETERS: int nEntries - how many AdrEntries to allocate in new list // int nProps - how many properties per new AdrEntry // LPADRLIST * lppAdrList - where to return the allocated ptr // BOOL GrowAdrList(IN UINT nEntries, IN UINT nProps, OUT LPADRLIST * lppAdrList) { BOOL retval = TRUE; SCODE sc; LPADRLIST lpTempAdrList; unsigned int entry; if ((!lppAdrList) || ((*lppAdrList)->cEntries>=nEntries)) return FALSE; #ifdef PAB if (! (sc = MAPIAllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)), (void **)&lpTempAdrList))) { lpTempAdrList->cEntries = nEntries; // Copy over old entries entry = (*lppAdrList)->cEntries; memcpy(lpTempAdrList, *lppAdrList, (entry * sizeof(ADRENTRY))); // Allocate new entries for (; entry < nEntries; entry++) { lpTempAdrList->aEntries[entry].ulReserved1 = 0; lpTempAdrList->aEntries[entry].cValues = nProps; sc = MAPIAllocateBuffer((nProps * sizeof(SPropValue)), (void **)(&lpTempAdrList->aEntries[entry].rgPropVals)); if (sc != S_OK) retval = FALSE; } FreeAdrList(lppAdrList); *lppAdrList = lpTempAdrList; } else retval = FALSE; // // Should do cleanup here for a partial allocation that fails // #endif //PAB #ifdef WAB if (! (sc = lpWABObject->AllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)), (void **)&lpTempAdrList))) { // Copy over old entries entry = (*lppAdrList)->cEntries; memcpy(lpTempAdrList, *lppAdrList, (sizeof(ADRLIST)+(entry * sizeof(ADRENTRY)))); lpTempAdrList->cEntries = nEntries; // Allocate new entries for (; entry < nEntries; entry++) { lpTempAdrList->aEntries[entry].ulReserved1 = 0; lpTempAdrList->aEntries[entry].cValues = nProps; sc = lpWABObject->AllocateBuffer((nProps * sizeof(SPropValue)), (void **)(&lpTempAdrList->aEntries[entry].rgPropVals)); if (sc != S_OK) retval = FALSE; } FreePartAdrList(lppAdrList); *lppAdrList = lpTempAdrList; } else retval = FALSE; // // Should do cleanup here for a partial allocation that fails // #endif //WAB return retval; } // // PROCEDURE: FreeAdrList // DESCRIPTION: Uses either MAPI or WAB de-allocaters to walk and free an lpAdrList // // PARAMETERS: LPWABOBJECT lpLocalWABObject - ptr to opened WABObject // LPADRLIST * lppAdrList - where the lpAdrList to free is stored // BOOL FreeAdrList(IN LPWABOBJECT lpLocalWABObject, IN LPADRLIST * lppAdrList) { LPADRLIST lpAdrList = NULL; UINT idx; if (lppAdrList) lpAdrList = *lppAdrList; #ifdef PAB if (lpAdrList) { for (idx = 0; idx < lpAdrList->cEntries; idx++) MAPIFreeBuffer(lpAdrList->aEntries[idx].rgPropVals); MAPIFreeBuffer(lpAdrList); *lppAdrList=NULL; } #endif //PAB #ifdef WAB if (lpAdrList) { for (idx = 0; idx < lpAdrList->cEntries; idx++) lpLocalWABObject->FreeBuffer(lpAdrList->aEntries[idx].rgPropVals); lpLocalWABObject->FreeBuffer(lpAdrList); *lppAdrList=NULL; } #endif //WAB return TRUE; } // // PROCEDURE: FreePartAdrList // DESCRIPTION: Uses either MAPI or WAB de-allocaters to free an lpAdrList // but not the associated properties. // // PARAMETERS: LPADRLIST * lppAdrList - where the lpAdrList to free is stored // BOOL FreePartAdrList(IN LPADRLIST * lppAdrList) { LPADRLIST lpAdrList = NULL; if (lppAdrList) lpAdrList = *lppAdrList; #ifdef PAB if (lpAdrList) { MAPIFreeBuffer(lpAdrList); lpAdrList=NULL; } #endif //PAB #ifdef WAB if (lpAdrList) { lpWABObject->FreeBuffer(lpAdrList); lpAdrList=NULL; } #endif //WAB return TRUE; } // // PROCEDURE: FindProp // DESCRIPTION: Walks through the properties of an AdrEntry and returns the index // of the requested property tag. // // PARAMETERS: LPADRENTRY lpAdrEntry - Entry to search through // ULONG ulPropTag - Property tag to look for // unsigned int* lpnFoundIndex - Ptr to output variable where the found index // value is to be stored. // // RETURNS: TRUE if succesfull. // BOOL FindProp(IN LPADRENTRY lpAdrEntry, IN ULONG ulPropTag, OUT unsigned int* lpnFoundIndex) { if ((!lpAdrEntry) || (!ulPropTag) || (!lpnFoundIndex)) return(FALSE); for (unsigned int Counter1 = 0; Counter1 < lpAdrEntry->cValues; Counter1++) { if (lpAdrEntry->rgPropVals[Counter1].ulPropTag == ulPropTag) { *lpnFoundIndex = Counter1; return(TRUE); } } return(FALSE); } // // PROCEDURE: FindPropinRow // DESCRIPTION: Walks through the properties of an SRowSet and returns the index // of the requested property tag. // // PARAMETERS: LPSRow lpRow - Row to search through // ULONG ulPropTag - Property tag to look for // unsigned int* lpnFoundIndex - Ptr to output variable where the found index // value is to be stored. // // RETURNS: TRUE if succesfull. // BOOL FindPropinRow(IN LPSRow lpRow, IN ULONG ulPropTag, OUT unsigned int* lpnFoundIndex) { if ((!lpRow) || (!ulPropTag) || (!lpnFoundIndex)) return(FALSE); for (ULONG Column = 0; Column < lpRow->cValues; Column++) { if (lpRow->lpProps[Column].ulPropTag == ulPropTag) { *lpnFoundIndex = Column; return(TRUE); } } return(FALSE); } // // PROCEDURE: ParseIniBuffer // DESCRIPTION: Walks through a buffer read from an ini file which contains // several strings separated by quotation marks and copies the // requested string to the users buffer. // // PARAMETERS: LPSTR lpszIniBuffer // UINT uSelect - which string (in order left to right starting with 1 ) to return // LPSTR lpszReturnBuffer - pre-alocated by caller and dumb (assumes enough space) // BOOL ParseIniBuffer(LPSTR lpszIniBuffer, UINT uSelect, LPSTR lpszReturnBuffer) { UINT Selected = 0; // while (*(lpszIniBuffer++) != '"'); // Advance to first entry // lpszIniBuffer++; Selected++; // Now pointing at 1st letter of first item while(uSelect != Selected++) { while (*(lpszIniBuffer++) != '"'); // Advance to end of this entry while (*(lpszIniBuffer++) != '"'); // Advance to beginning of next entry // Now we are pointing at the 1st letter of the desired entry so copy } while((*(lpszIniBuffer) != '"') && (*(lpszIniBuffer) != '\0')) { *(lpszReturnBuffer++) = *lpszIniBuffer++; } *lpszReturnBuffer = '\0'; // Add the terminator return(TRUE); } // // PROCEDURE: PropError // DESCRIPTION: Compares the passed in property type with PT_ERROR returning TRUE is error is found // // PARAMETERS: ulPropTag - Tag to compare // cValues - # of entries returned from GetProps // BOOL PropError(ULONG ulPropTag, ULONG cValues) { BOOL retval = FALSE; #ifdef DISTLISTS for(ULONG Counter = 0; Counter < cValues; Counter++) { if (PROP_TYPE(ulPropTag) == PT_ERROR) retval = TRUE; } #endif return retval; } // // PROCEDURE: DeleteWABFile // DESCRIPTION: Reads the registry to determine the location of the WAB file, // and deletes the file. // // PARAMETERS: none // BOOL DeleteWABFile () { BOOL retval = TRUE; long lretval; HKEY hKey; char KeyAddress[] = "Software\\Microsoft\\WAB\\Wab File Name"; DWORD dType, dSize = 256; char achData[256]; if (!MyRegOpenKeyEx(HKEY_CURRENT_USER, KeyAddress, KEY_QUERY_VALUE, &hKey)) { LUIOut(L2, "MyRegOpenKeyEx call failed"); retval = FALSE; return(retval); } lretval = RegQueryValueEx(hKey, // handle of key to query NULL, // address of name of value to query (LPDWORD)NULL, // reserved &dType, // address of buffer for value type (LPBYTE)achData, // address of data buffer &dSize // address of data buffer size ); if (lretval != ERROR_SUCCESS) { LUIOut(L2, "RegQueryValueEx call failed with error code %u", lretval); retval = FALSE; return(retval); } LUIOut(L2, "Deleting WAB file: %s", achData); RegCloseKey(hKey); if (!DeleteFile(achData)) { LUIOut(L3, "Delete FAILED. Could not locate or delete file."); retval = FALSE; } return(retval); } // // PROCEDURE: MyRegOpenKeyEx // DESCRIPTION: Walks through a null terminated string, such as "\Software\Microsoft\WAB" // openning each key until it reaches the end and returns that open key (closing // the interim keys along the way). The caller must close the returned HKEY. // // PARAMETERS: StartKey - one of the predefined "open" keys to root at // szAddress - null terminated string specifcying the path to the key to be opened // RegSec - the security access required (i.e. KEY_READ) // lpReturnKey - address of HKEY where final opened key is stored // BOOL MyRegOpenKeyEx(HKEY StartKey, char* szAddress, REGSAM RegSec, HKEY* lpReturnKey) { HKEY workkey1, workkey2, *lpOpenKey=&workkey1, *lpNewKey=&workkey2; char workbuffer[256], *lpAddr = szAddress, *lpWork = workbuffer; BOOL Started = FALSE, Done = FALSE; long lretval; if (!szAddress) return FALSE; while (!Done) { if (*lpAddr == '\\') lpAddr++; //skip over the initial backslash if it exists while((*(lpAddr) != '\\') && (*(lpAddr) != '\0')) { *(lpWork++) = *lpAddr++; } *lpWork = '\0'; // Add the terminator if (*(lpAddr) == '\0') Done = TRUE; lpWork = workbuffer; if (!Started) { // // First, special case the starting key (predefined/open key root) // lretval = RegOpenKeyEx( StartKey, lpWork, DWORD(0), RegSec, lpOpenKey); Started = TRUE; } else { lretval = RegOpenKeyEx( *lpOpenKey, lpWork, DWORD(0), RegSec, lpNewKey); RegCloseKey(*lpOpenKey); *lpOpenKey = *lpNewKey; } if (lretval != ERROR_SUCCESS) { LUIOut(L2, "RegOpenKeyEx call failed with error code 0x%x", lretval); return(FALSE); } } *lpReturnKey = *lpNewKey; return(TRUE); } // // PROCEDURE: CreateMultipleEntries // DESCRIPTION: Creates multiple entries in the WAB using the display name stored in the // pabtests.ini file CreateEntriesStress section. // // PARAMETERS: NumEntriesIn - how many entries to create. If 0, then the value is read // from the same CreateEntriesStress section. // lpPerfData - address of a dword data type to hold the average time in milliseconds // required during SaveChanges. If NULL perf data is not accumulated. // BOOL CreateMultipleEntries(IN UINT NumEntriesIn, DWORD* lpPerfData) { ULONG ulFlags = 0; HRESULT hr = hrSuccess; SCODE sc = SUCCESS_SUCCESS; int retval=TRUE; DWORD StartTime, StopTime; LPADRBOOK lpAdrBook = NULL; LPABCONT lpABCont= NULL; ULONG cbEidPAB = 0; LPENTRYID lpEidPAB = NULL; char EntProp[10][BIG_BUF]; //MAX_PROP ULONG cValues = 0, ulObjType=NULL; int i=0,k=0; char EntryBuf[MAX_BUF]; char szDLTag[SML_BUF]; unsigned int NumEntries, counter, StrLen; LPMAILUSER lpMailUser=NULL,lpDistList=NULL; SPropValue PropValue[3] = {0}; // This value is 3 because we // will be setting 3 properties: // EmailAddress, DisplayName and // AddressType. LPSPropValue lpSPropValueAddress = NULL; LPSPropValue lpSPropValueDL = NULL; SizedSPropTagArray(1,SPTArrayAddress) = {1, {PR_DEF_CREATE_MAILUSER} }; SizedSPropTagArray(1,SPTArrayDL) = {1, {PR_DEF_CREATE_DL} }; if (!GetAB(OUT &lpAdrBook)) { retval = FALSE; goto out; } // Call IAddrBook::OpenEntry to get the root container to PAB - MAPI assert(lpAdrBook != NULL); hr = OpenPABID( IN lpAdrBook, OUT &cbEidPAB, OUT &lpEidPAB,OUT &lpABCont, OUT &ulObjType); // hr = lpAdrBook->OpenEntry(0, NULL, NULL,MAPI_MODIFY,&ulObjType, (LPUNKNOWN *) &lpABCont); if (HR_FAILED(hr)) { LUIOut(L2,"IAddrBook->OpenEntry Failed"); retval=FALSE; goto out; } // Wipe perfdata if we're tracking this if (lpPerfData) *lpPerfData = (DWORD)0; // // Try to create a MailUser entry in the container // // Need to get the template ID so we call GetProps with PR_DEF_CREATE_MAILUSER assert(lpABCont != NULL); hr = lpABCont->GetProps( IN (LPSPropTagArray) &SPTArrayAddress, IN 0, //Flags OUT &cValues, OUT &lpSPropValueAddress); if ((HR_FAILED(hr))||(PropError(lpSPropValueAddress->ulPropTag, cValues))) { LUIOut(L3,"GetProps FAILED for Default MailUser template"); retval=FALSE; goto out; } // The returned value of PR_DEF_CREATE_MAILUSER is an // EntryID which can be passed to CreateEntry // // Retrieve user info from ini file cValues = 3; //# of props we are setting lstrcpy(szDLTag,"Address1"); GetPrivateProfileString("CreateEntriesStress",szDLTag,"",EntryBuf,MAX_BUF,INIFILENAME); GetPropsFromIniBufEntry(EntryBuf,cValues,EntProp); StrLen = (strlen(EntProp[0])); _itoa(0,(char*)&EntProp[0][StrLen],10); EntProp[0][StrLen+1]= '\0'; NumEntries = (NumEntriesIn > 0) ? NumEntriesIn:GetPrivateProfileInt("CreateEntriesStress","NumCopies",0,INIFILENAME); if (NumEntries > 100) LUIOut(L2, "Adding %u MailUser entries to the WAB. This may take several minutes.", NumEntries); for (counter = 0; counter < NumEntries; counter++) { // LUIOut(L3, "Calling IABContainer->CreateEntry with the EID from GetProps"); hr = lpABCont->CreateEntry( IN lpSPropValueAddress->Value.bin.cb, IN (LPENTRYID) lpSPropValueAddress->Value.bin.lpb, IN 0, OUT (LPMAPIPROP *) &lpMailUser); if (HR_FAILED(hr)) { LUIOut(L3,"CreateEntry failed for PR_DEF_CREATE_MAILUSER"); retval=FALSE; goto out; } // // Then set the properties // PropValue[0].ulPropTag = PR_DISPLAY_NAME; PropValue[1].ulPropTag = PR_ADDRTYPE; PropValue[2].ulPropTag = PR_EMAIL_ADDRESS; _itoa(counter,(char*)&EntProp[0][StrLen],10); // LUIOut(L2,"MailUser Entry to Add: %s",EntProp[0]); for (i=0; i<(int)cValues;i++) PropValue[i].Value.LPSZ = (LPTSTR)EntProp[i]; hr = lpMailUser->SetProps(IN cValues, IN PropValue, IN NULL); if (HR_FAILED(hr)) { LUIOut(L3,"MailUser->SetProps call FAILED for %s properties",PropValue[0].Value.LPSZ); retval=FALSE; goto out; } // else LUIOut(L3,"MailUser->SetProps call PASSED for %s properties",PropValue[0].Value.LPSZ); StartTime = GetTickCount(); hr = lpMailUser->SaveChanges(IN KEEP_OPEN_READWRITE); //flags StopTime = GetTickCount(); /* if (lpPerfData) { if ((StopTime-StartTime) > *lpPerfData) *lpPerfData = (StopTime - StartTime); } */ if (lpPerfData) { *lpPerfData += (StopTime - StartTime); } if (HR_FAILED(hr)) { LUIOut(L3,"MailUser->SaveChanges FAILED"); retval=FALSE; goto out; } // else LUIOut(L3,"MailUser->SaveChanges PASSED, entry added to PAB/WAB"); if (lpMailUser) { lpMailUser->Release(); lpMailUser = NULL; } } if (lpPerfData) *lpPerfData /= NumEntries; out: #ifdef PAB if (lpEid) MAPIFreeBuffer(lpEid); if (lpEidPAB) MAPIFreeBuffer(lpEidPAB); if (lpSPropValueAddress) MAPIFreeBuffer(lpSPropValueAddress); if (lpSPropValueDL) MAPIFreeBuffer(lpSPropValueDL); #endif #ifdef WAB if (lpEidPAB) lpWABObject->FreeBuffer(lpEidPAB); if (lpSPropValueAddress) lpWABObject->FreeBuffer(lpSPropValueAddress); if (lpSPropValueDL) lpWABObject->FreeBuffer(lpSPropValueDL); #endif if (lpMailUser) lpMailUser->Release(); if (lpDistList) lpDistList->Release(); if (lpABCont) lpABCont->Release(); if (lpAdrBook) lpAdrBook->Release(); #ifdef PAB if (lpMAPISession) lpMAPISession->Release(); MAPIUninitialize(); #endif #ifdef WAB if (lpWABObject) { lpWABObject->Release(); lpWABObject = NULL; } #endif return retval; } void GenerateRandomPhoneNumber(char **lppPhone) { #define FORMATSIZE 15 // Size of formatted phone# + terminator i.e. (206)-882-8080 #define MAXNUMSIZE (FORMATSIZE + 32) unsigned int Offset = 0; extern BOOL Seeded; *lppPhone = (char*)LocalAlloc(LMEM_FIXED, MAXNUMSIZE*sizeof(char)); (*lppPhone)[0] = '\0'; // Set the first char to a terminator // seed the random number generator with the current time if (!Seeded) { srand( (unsigned)GetTickCount()); Seeded = TRUE; } while (Offset < FORMATSIZE) { _itoa(rand(), ((*lppPhone)+Offset), 10); Offset = strlen(*lppPhone); } // Overwrite some numbers with formatting characters (*lppPhone)[0] = '('; (*lppPhone)[4] = ')'; (*lppPhone)[5] = '-'; (*lppPhone)[9] = '-'; (*lppPhone)[FORMATSIZE-1] = '\0'; //Cutoff the end in case it's > FORMATSIZE } void GenerateRandomText(char **lppText, UINT unSize) { unsigned int Offset = 0; extern BOOL Seeded; extern ULONG glblTest, glblCount, glblDN; *lppText = (char*)LocalAlloc(LMEM_FIXED, (unSize+1)*sizeof(char)); // seed the random number generator with the current time if (!Seeded) { srand( (unsigned)GetTickCount()); Seeded = TRUE; } #ifdef TESTPASS for (Offset = 0; Offset < unSize; Offset++) { (*lppText)[Offset] = (char)glblTest; if ((*lppText)[Offset] == '\0') (*lppText)[Offset] = (char)'?'; //don't want a terminator mid string } (*lppText)[unSize] = '\0'; //Cutoff the end if (glblDN) { glblDN = 0; if (++glblCount == 15) { glblTest++; glblCount=0; LUIOut(L4, "Testing value %i [%c].", glblTest, glblTest); } } #else for (Offset = 0; Offset < unSize; Offset++) { (*lppText)[Offset] = rand(); if ((*lppText)[Offset] == '\0') (*lppText)[Offset] = (char)'?'; //don't want a terminator mid string } (*lppText)[unSize] = '\0'; //Cutoff the end #endif } void GenerateRandomBoolean(unsigned short *lpBool) { extern BOOL Seeded; // seed the random number generator with the current time if (!Seeded) { srand( (unsigned)GetTickCount()); Seeded = TRUE; } *lpBool = (unsigned short)(GetTickCount() & 0x01); //If bit 0 is set then true otherwise false } void GenerateRandomLong(long *lpLong) { extern BOOL Seeded; // seed the random number generator with the current time if (!Seeded) { srand( (unsigned)GetTickCount()); Seeded = TRUE; } *lpLong = (long)rand(); } void GenerateRandomBinary(SBinary *lpBinary, UINT unSize) { unsigned int Offset = 0; extern BOOL Seeded; lpBinary->lpb = (LPBYTE)LocalAlloc(LMEM_FIXED, unSize); lpBinary->cb = unSize; // seed the random number generator with the current time if (!Seeded) { srand( (unsigned)GetTickCount()); Seeded = TRUE; } for (Offset = 0; Offset < unSize; Offset++) { lpBinary->lpb[Offset] = (BYTE)(rand() * 255)/RAND_MAX; } } //*** //*** set unCount to AUTONUM_OFF to disable autonumbering display names //*** if lppDisplayName is not NULL then the *lppDisplayName string is used for the prefix of //*** the DN and the ptr to the completed DisplayName is returned to the callee if lppReturnName is not NULL //*** void CreateProps(LPTSTR lpszFileName, LPTSTR lpszSection, SPropValue** lppProperties, ULONG* lpcValues, UINT unCount, char** lppDisplayName, char ** lppReturnName) { UINT StrLen1, PropIndex = 0, Properties = 0; //How many props does the user want to set char *lpszLocalDisplayName, DNText[] = {"Test Entry #"}; extern ULONG glblDN; PropTableEntry* lpEntry = PropTable; while (lpEntry->ulPropTag) { lpEntry->unSize = GetPrivateProfileInt(lpszSection,lpEntry->lpszPropTag,0,lpszFileName); if ((lpEntry->ulPropTag == PR_DISPLAY_NAME) && (unCount != AUTONUM_OFF)) lpEntry->unSize = TRUE; //If we're autonumbering the display name, then make sure unsize is not zero if (lpEntry->unSize) Properties++; lpEntry++; } //At this point, any table entry with nonzero size we need to create //LUIOut(L3, "Setting %i properties.", Properties); *lpcValues = Properties; *lppProperties = (SPropValue*)LocalAlloc(LMEM_FIXED, (Properties * sizeof(SPropValue))); lpEntry = PropTable; while (lpEntry->ulPropTag) { if (lpEntry->unSize) { //special case phone numbers if ((strstr(lpEntry->lpszPropTag, "PHONE")) || (strstr(lpEntry->lpszPropTag, "FAX"))) { //LUIOut(L3, "Found a prop I think is a phone number, called %s.", lpEntry->lpszPropTag); (*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag; GenerateRandomPhoneNumber(&((*lppProperties)[PropIndex].Value.LPSZ)); } //special case for autonumbering display names if requested else if ((lpEntry->ulPropTag == PR_DISPLAY_NAME) && (unCount != AUTONUM_OFF)) { if ((lppDisplayName)&&(*lppDisplayName)) { //Caller passed in a string to use as the prefix StrLen1 = strlen(*lppDisplayName); lpszLocalDisplayName = (char*)LocalAlloc(LMEM_FIXED, (StrLen1+5)*sizeof(char)); //5 for terminator plus # up to 9999 strcpy(lpszLocalDisplayName, *lppDisplayName); } else { StrLen1 = strlen(DNText); lpszLocalDisplayName = (char*)LocalAlloc(LMEM_FIXED, (StrLen1+5)*sizeof(char)); //5 for terminator plus # up to 9999 strcpy(lpszLocalDisplayName, DNText); } // Add the Entry # to the display name _itoa(unCount,(char*)&(lpszLocalDisplayName[StrLen1]),10); (*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag; (*lppProperties)[PropIndex].Value.LPSZ = lpszLocalDisplayName; if (lppReturnName) *lppReturnName = lpszLocalDisplayName; } else { switch(PROP_TYPE(lpEntry->ulPropTag)) { case PT_STRING8: (*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag; #ifdef TESTPASS if (lpEntry->ulPropTag == PR_DISPLAY_NAME) glblDN = 1; #endif GenerateRandomText(&((*lppProperties)[PropIndex].Value.LPSZ),lpEntry->unSize); if ((lpEntry->ulPropTag == PR_DISPLAY_NAME) && lppReturnName) *lppReturnName = (*lppProperties)[PropIndex].Value.LPSZ; break; case PT_BOOLEAN: (*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag; GenerateRandomBoolean(&((*lppProperties)[PropIndex].Value.b)); break; case PT_LONG: (*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag; GenerateRandomLong(&((*lppProperties)[PropIndex].Value.l)); break; case PT_BINARY: (*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag; GenerateRandomBinary(&((*lppProperties)[PropIndex].Value.bin),lpEntry->unSize); break; default: LUIOut(L1, "Unrecognized prop type 0x%x for property %s", PROP_TYPE(lpEntry->ulPropTag), lpEntry->lpszPropTag); } } PropIndex++; } lpEntry++; } } //*** //*** Walks through the expected props and searches the found props for the same prop/value combo //*** BOOL CompareProps(SPropValue* lpExpectedProps, ULONG cValuesExpected, SPropValue* lpCompareProps, ULONG cValuesCompare) { ULONG TargetProp, CompareIndex; BOOL Result = TRUE, Found; for (ULONG PropertyIndex = 0; PropertyIndex < cValuesExpected; PropertyIndex++) { TargetProp = lpExpectedProps[PropertyIndex].ulPropTag; for (CompareIndex = 0, Found = FALSE; CompareIndex < cValuesCompare; CompareIndex++) { if (lpCompareProps[CompareIndex].ulPropTag == TargetProp) { //if (TargetProp == PR_DISPLAY_NAME) _asm{int 3}; Found = TRUE; switch(PROP_TYPE(TargetProp)) { case PT_STRING8: if (strcmp(lpExpectedProps[PropertyIndex].Value.LPSZ, lpCompareProps[CompareIndex].Value.LPSZ)) { //Strings did not match so fail compare LUIOut(L3, "Comparison failed for prop 0x%x. Expected %s but found %s", TargetProp, lpExpectedProps[PropertyIndex].Value.LPSZ, lpCompareProps[CompareIndex].Value.LPSZ); Result = FALSE; //_asm{int 3}; } break; case PT_BOOLEAN: if (lpExpectedProps[PropertyIndex].Value.b != lpCompareProps[CompareIndex].Value.b) { //bools did not match so fail compare LUIOut(L3, "Comparison failed for prop 0x%x. Expected %u but found %u", TargetProp, lpExpectedProps[PropertyIndex].Value.b, lpCompareProps[CompareIndex].Value.b); Result = FALSE; } break; case PT_LONG: if (lpExpectedProps[PropertyIndex].Value.l != lpCompareProps[CompareIndex].Value.l) { //bools did not match so fail compare LUIOut(L3, "Comparison failed for prop 0x%x. Expected %u but found %u", TargetProp, lpExpectedProps[PropertyIndex].Value.l, lpCompareProps[CompareIndex].Value.l); Result = FALSE; } break; case PT_BINARY: if (memcmp(lpExpectedProps[PropertyIndex].Value.bin.lpb, lpCompareProps[CompareIndex].Value.bin.lpb, lpExpectedProps[PropertyIndex].Value.bin.cb)) { //bools did not match so fail compare LUIOut(L3, "Comparison failed for prop 0x%x. %u bytes expected, %u found and they are not equal", TargetProp, lpExpectedProps[PropertyIndex].Value.bin.cb, lpCompareProps[CompareIndex].Value.bin.cb); Result = FALSE; } break; default: LUIOut(L3, "Unrecognized prop type 0x%x", PROP_TYPE(lpExpectedProps[PropertyIndex].ulPropTag)); } //switch } //if propr match } //for loop (CompareIndex) if (!Found) { LUIOut(L3, "Did not find property 0x%x. Compare FAILS", TargetProp); Result = FALSE; } } //for loop (PropertyIndex) //LUIOut(L3, "%u propertes compared %s", PropertyIndex, Result ? "Successfully" : "With Errors"); return(Result); } //CompareProps() //*** //*** Walks through the expected props until it finds the target prop and displays its value //*** BOOL DisplayProp(SPropValue *lpSearchProps, ULONG ulTargetProp, ULONG cValues) { BOOL Result = TRUE, Found = FALSE; for (ULONG PropertyIndex = 0; PropertyIndex < cValues; PropertyIndex++) { if (lpSearchProps[PropertyIndex].ulPropTag == ulTargetProp) { //if (TargetProp == PR_DISPLAY_NAME) _asm{int 3}; Found = TRUE; switch(PROP_TYPE(ulTargetProp)) { case PT_STRING8: LUIOut(L4, "Property 0x%x has value:%s", ulTargetProp, lpSearchProps[PropertyIndex].Value.LPSZ); break; case PT_BOOLEAN: LUIOut(L4, "Property 0x%x has value:%i", ulTargetProp, lpSearchProps[PropertyIndex].Value.b); break; case PT_LONG: LUIOut(L4, "Property 0x%x has value:0x%x", ulTargetProp, lpSearchProps[PropertyIndex].Value.l); break; case PT_BINARY: LUIOut(L4, "Binary prop found but not displayed."); break; default: LUIOut(L3, "Unrecognized prop type 0x%x", PROP_TYPE(ulTargetProp)); } //switch } //if propr match } //for loop (PropertyIndex) if (!Found) { LUIOut(L4, "Did not find property 0x%x.", ulTargetProp); Result = FALSE; } return(Result); } //DisplayProp()