//$--HrMAPICreateSizedAddressList------------------------------------------------ // Create a sized address list. // ----------------------------------------------------------------------------- HRESULT HrMAPICreateSizedAddressList( // RETURNS: return code IN ULONG cEntries, // count of entries in address list OUT LPADRLIST *lppAdrList) // pointer to address list pointer { HRESULT hr = NOERROR; SCODE sc = 0; ULONG cBytes = 0; DEBUGPUBLIC("HrMAPICreateAddressList()\n"); hr = CHK_HrMAPICreateSizedAddressList( cEntries, lppAdrList); if(FAILED(hr)) RETURN(hr); *lppAdrList = NULL; cBytes = CbNewADRLIST(cEntries); sc = MAPIAllocateBuffer(cBytes, (LPVOID*)lppAdrList); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Initialize ADRLIST structure ZeroMemory(*lppAdrList, cBytes); (*lppAdrList)->cEntries = cEntries; cleanup: RETURN(hr); }
// Manually resolve a name in the address book and add it to the message _Check_return_ HRESULT ManualResolve( _In_ LPMAPISESSION lpMAPISession, _In_ LPMESSAGE lpMessage, _In_z_ LPCTSTR szName, ULONG PropTagToCompare) { HRESULT hRes = S_OK; ULONG ulObjType = 0; LPADRBOOK lpAdrBook = NULL; LPSRowSet lpABRow = NULL; LPMAPITABLE lpABContainerTable = NULL; LPADRLIST lpAdrList = NULL; LPABCONT lpABContainer = NULL; LPMAPITABLE pTable = NULL; LPSPropValue lpFoundRow = NULL; enum { abcPR_ENTRYID, abcPR_DISPLAY_NAME, abcNUM_COLS }; static const SizedSPropTagArray(abcNUM_COLS, abcCols) = { abcNUM_COLS, PR_ENTRYID, PR_DISPLAY_NAME, }; enum { abPR_ENTRYID, abPR_DISPLAY_NAME, abPR_RECIPIENT_TYPE, abPR_ADDRTYPE, abPR_DISPLAY_TYPE, abPropTagToCompare, abNUM_COLS }; if (!lpMAPISession) return MAPI_E_INVALID_PARAMETER; DebugPrint(DBGGeneric, _T("ManualResolve: Asked to resolve \"%s\"\n"), szName); EC_MAPI(lpMAPISession->OpenAddressBook( NULL, NULL, NULL, &lpAdrBook)); EC_H(GetABContainerTable(lpAdrBook, &lpABContainerTable)); if (lpABContainerTable) { // Restrict the table to the properties that we are interested in. EC_MAPI(lpABContainerTable->SetColumns((LPSPropTagArray)&abcCols, TBL_BATCH)); if (!FAILED(hRes)) for (;;) { hRes = S_OK; FreeProws(lpABRow); lpABRow = NULL; EC_MAPI(lpABContainerTable->QueryRows( 1, NULL, &lpABRow)); if (FAILED(hRes) || !lpABRow || (lpABRow && !lpABRow->cRows)) break; // From this point forward, consider any error an error with the current address book container, so just continue and try the next one. if (PR_ENTRYID == lpABRow->aRow->lpProps[abcPR_ENTRYID].ulPropTag) { DebugPrint(DBGGeneric, _T("ManualResolve: Searching this container\n")); DebugPrintBinary(DBGGeneric, &lpABRow->aRow->lpProps[abcPR_ENTRYID].Value.bin); if (lpABContainer) lpABContainer->Release(); lpABContainer = NULL; EC_H(CallOpenEntry( NULL, lpAdrBook, NULL, NULL, lpABRow->aRow->lpProps[abcPR_ENTRYID].Value.bin.cb, (ENTRYID*)lpABRow->aRow->lpProps[abcPR_ENTRYID].Value.bin.lpb, NULL, NULL, &ulObjType, (LPUNKNOWN*)&lpABContainer)); if (!lpABContainer) continue; DebugPrint(DBGGeneric, _T("ManualResolve: Object opened as 0x%X\n"), ulObjType); if (lpABContainer && ulObjType == MAPI_ABCONT) { if (pTable) pTable->Release(); pTable = NULL; WC_MAPI(lpABContainer->GetContentsTable(fMapiUnicode, &pTable)); if (!pTable) { DebugPrint(DBGGeneric, _T("ManualResolve: Container did not support contents table\n")); if (MAPI_E_NO_SUPPORT == hRes) hRes = S_OK; continue; } MAPIFreeBuffer(lpFoundRow); lpFoundRow = NULL; EC_H(SearchContentsTableForName( pTable, szName, PropTagToCompare, &lpFoundRow)); if (!lpFoundRow) continue; if (lpAdrList) FreePadrlist(lpAdrList); lpAdrList = NULL; // Allocate memory for new Address List structure. EC_H(MAPIAllocateBuffer(CbNewADRLIST(1), (LPVOID*)&lpAdrList)); if (!lpAdrList) continue; ZeroMemory(lpAdrList, CbNewADRLIST(1)); lpAdrList->cEntries = 1; // Allocate memory for SPropValue structure that indicates what // recipient properties will be set. To resolve a name that // already exists in the Address book, this will always be 1. EC_H(MAPIAllocateBuffer( (ULONG)(abNUM_COLS * sizeof(SPropValue)), (LPVOID*)&lpAdrList->aEntries->rgPropVals)); if (!lpAdrList->aEntries->rgPropVals) continue; // TODO: We are setting 5 properties below. If this changes, modify these two lines. ZeroMemory(lpAdrList->aEntries->rgPropVals, 5 * sizeof(SPropValue)); lpAdrList->aEntries->cValues = 5; // Fill out addresslist with required property values. LPSPropValue pProps = lpAdrList->aEntries->rgPropVals; LPSPropValue pProp; // Just a pointer, do not free. pProp = &pProps[abPR_ENTRYID]; pProp->ulPropTag = PR_ENTRYID; EC_H(CopySBinary(&pProp->Value.bin, &lpFoundRow[abPR_ENTRYID].Value.bin, lpAdrList)); pProp = &pProps[abPR_RECIPIENT_TYPE]; pProp->ulPropTag = PR_RECIPIENT_TYPE; pProp->Value.l = MAPI_TO; pProp = &pProps[abPR_DISPLAY_NAME]; pProp->ulPropTag = PR_DISPLAY_NAME; if (!CheckStringProp(&lpFoundRow[abPR_DISPLAY_NAME], PT_TSTRING)) continue; EC_H(CopyString( &pProp->Value.LPSZ, lpFoundRow[abPR_DISPLAY_NAME].Value.LPSZ, lpAdrList)); pProp = &pProps[abPR_ADDRTYPE]; pProp->ulPropTag = PR_ADDRTYPE; if (!CheckStringProp(&lpFoundRow[abPR_ADDRTYPE], PT_TSTRING)) continue; EC_H(CopyString( &pProp->Value.LPSZ, lpFoundRow[abPR_ADDRTYPE].Value.LPSZ, lpAdrList)); pProp = &pProps[abPR_DISPLAY_TYPE]; pProp->ulPropTag = PR_DISPLAY_TYPE; pProp->Value.l = lpFoundRow[abPR_DISPLAY_TYPE].Value.l; EC_MAPI(lpMessage->ModifyRecipients( MODRECIP_ADD, lpAdrList)); if (lpAdrList) FreePadrlist(lpAdrList); lpAdrList = NULL; EC_MAPI(lpMessage->SaveChanges(KEEP_OPEN_READWRITE)); // since we're done with our work, let's get out of here. break; } } } lpABContainerTable->Release(); } FreeProws(lpABRow); MAPIFreeBuffer(lpFoundRow); if (lpAdrList) FreePadrlist(lpAdrList); if (pTable) pTable->Release(); if (lpABContainer) lpABContainer->Release(); if (lpAdrBook) lpAdrBook->Release(); return hRes; } // ManualResolve
//$--HrMAPIAppendAddressList----------------------------------------------------- // Append to an address list. // ----------------------------------------------------------------------------- HRESULT HrMAPIAppendAddressList( // RETURNS: return code IN ULONG cProps, // count of values in address list // entry IN LPSPropValue lpPropValues, // pointer to address list entry IN OUT LPADRLIST *lppAdrList) // pointer to address list pointer { HRESULT hr = NOERROR; SCODE sc = 0; LPADRLIST lpAdrList = NULL; LPADRENTRY lpAdrEntry = NULL; LPSPropValue lpNewPropValues = NULL; ULONG i = 0; ULONG cBytes = 0; ULONG cEntries = 0; DEBUGPUBLIC("HrMAPIAppendAddressList()\n"); hr = CHK_HrMAPIAppendAddressList( cProps, lpPropValues, lppAdrList); if(FAILED(hr)) RETURN(hr); sc = ScDupPropset( cProps, lpPropValues, MAPIAllocateBuffer, &lpNewPropValues); if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } cEntries = ((*lppAdrList)->cEntries + 1); cBytes = CbNewADRLIST(cEntries); sc = MAPIAllocateBuffer(cBytes, (void **)&lpAdrList); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Initialize ADRLIST ZeroMemory(lpAdrList, cBytes); lpAdrEntry = lpAdrList->aEntries; // Copy old ADRENTRY values to array for(i = 0; i < (*lppAdrList)->cEntries; i++) { lpAdrEntry[i].cValues = (*lppAdrList)->aEntries[i].cValues; lpAdrEntry[i].rgPropVals = (*lppAdrList)->aEntries[i].rgPropVals; } // Copy new ADRENTRY values to array lpAdrEntry[i].cValues = cProps; lpAdrEntry[i].rgPropVals = lpNewPropValues; lpAdrList->cEntries = (*lppAdrList)->cEntries + 1; MAPIFREEBUFFER(*lppAdrList); *lppAdrList = lpAdrList; cleanup: if(FAILED(hr)) { MAPIFREEBUFFER(lpNewPropValues); } RETURN(hr); }
//$--HrMAPICreateAddressList----------------------------------------------------- // Create an address list. // ----------------------------------------------------------------------------- HRESULT HrMAPICreateAddressList( // RETURNS: return code IN ULONG cProps, // count of values in address list // entry IN LPSPropValue lpPropValues, // pointer to address list entry OUT LPADRLIST *lppAdrList) // pointer to address list pointer { HRESULT hr = NOERROR; SCODE sc = 0; LPSPropValue lpNewPropValues = NULL; ULONG cBytes = 0; DEBUGPUBLIC("HrMAPICreateAddressList()\n"); hr = CHK_HrMAPICreateAddressList( cProps, lpPropValues, lppAdrList); if(FAILED(hr)) RETURN(hr); *lppAdrList = NULL; sc = ScDupPropset( cProps, lpPropValues, MAPIAllocateBuffer, &lpNewPropValues); if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } cBytes = CbNewADRLIST(1); sc = MAPIAllocateBuffer(cBytes, (LPVOID*)lppAdrList); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Initialize ADRLIST structure ZeroMemory(*lppAdrList, cBytes); (*lppAdrList)->cEntries = 1; (*lppAdrList)->aEntries[0].cValues = cProps; (*lppAdrList)->aEntries[0].rgPropVals = lpNewPropValues; cleanup: if(FAILED(hr)) { if(lppAdrList != NULL) { MAPIFREEBUFFER(*lppAdrList); *lppAdrList = NULL; } MAPIFREEBUFFER(lpNewPropValues); } RETURN(hr); }