Index: addrbook/src/nsAbOutlookDirFactory.cpp =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsAbOutlookDirFactory.cpp,v retrieving revision 1.9 diff -u -w -b -i -r1.9 nsAbOutlookDirFactory.cpp --- addrbook/src/nsAbOutlookDirFactory.cpp 25 Feb 2003 21:36:33 -0000 1.9 +++ addrbook/src/nsAbOutlookDirFactory.cpp 18 Sep 2003 09:03:12 -0000 @@ -124,8 +124,8 @@ nsCAutoString uri ; nsCOMPtr resource ; - for (ULONG i = 0 ; i < folders.mNbEntries ; ++ i) { - folders.mEntries [i].ToString(entryId) ; + for (ULONG i = 0 ; i < folders.GetSize() ; ++ i) { + folders[i].ToString(entryId) ; buildAbWinUri(kOutlookDirectoryScheme, abType, uri) ; uri.Append(entryId) ; Index: addrbook/src/nsAbOutlookDirectory.cpp =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsAbOutlookDirectory.cpp,v retrieving revision 1.17 diff -u -w -b -i -r1.17 nsAbOutlookDirectory.cpp --- addrbook/src/nsAbOutlookDirectory.cpp 23 May 2003 21:33:46 -0000 1.17 +++ addrbook/src/nsAbOutlookDirectory.cpp 18 Sep 2003 09:03:13 -0000 @@ -49,7 +49,6 @@ #include "nsIAddrBookSession.h" #include "nsAbQueryStringToExpression.h" #include "nsAbUtils.h" -#include "nsIProxyObjectManager.h" #include "prlog.h" #include "prthread.h" @@ -162,39 +161,76 @@ return retCode ; } +nsresult nsAbOutlookDirectory::BuildCardFromURI(const nsCString& uriName,nsIAbCard **aNewCard, + PRBool aSearchForOld, PRBool& aIsNewCard) +{ + nsresult retCode = NS_OK ; + if (aSearchForOld) { + nsCStringKey key(uriName) ; + nsCOMPtr existingCard = mCardList.Get(&key) ; + + if (existingCard) { + nsCOMPtr card(do_QueryInterface(existingCard, &retCode)) ; + + NS_ENSURE_SUCCESS(retCode, retCode) ; + NS_IF_ADDREF(*aNewCard = card) ; + aIsNewCard = PR_FALSE ; + return retCode ; + } + } + aIsNewCard = PR_TRUE ; + nsCOMPtr resource ; + + nsCOMPtr childCard = do_CreateInstance(NS_ABOUTLOOKCARD_CONTRACTID, &retCode); + NS_ENSURE_SUCCESS(retCode, retCode) ; + resource = do_QueryInterface(childCard, &retCode) ; + NS_ENSURE_SUCCESS(retCode, retCode) ; + retCode = resource->Init(uriName.get()) ; + NS_ENSURE_SUCCESS(retCode, retCode) ; + NS_IF_ADDREF(*aNewCard = childCard); + return retCode ; +} + NS_IMETHODIMP nsAbOutlookDirectory::GetChildCards(nsIEnumerator **aCards) { if (!aCards) { return NS_ERROR_NULL_POINTER ; } *aCards = nsnull ; nsCOMPtr cardList ; + nsCStringArray uriList ; + nsAbWinHelperGuard mapiAddBook (mAbWinType) ; nsresult retCode ; - mCardList.Reset() ; if (mIsQueryURI) { retCode = StartSearch() ; - NS_NewISupportsArray(getter_AddRefs(cardList)) ; } else { - retCode = GetChildCards(getter_AddRefs(cardList), nsnull) ; + retCode = GetChildCards(uriList, nsnull) ; } + NS_NewISupportsArray(getter_AddRefs(cardList)) ; if (NS_SUCCEEDED(retCode)) { // Fill the results array and update the card list // Also update the address list and notify any changes. PRUint32 nbCards = 0 ; - nsCOMPtr element ; + nsCAutoString uriName; + nsCOMPtr childCard; + PRBool searchForOldCards = (mCardList.Count() != 0) ; - cardList->Enumerate(aCards) ; - cardList->Count(&nbCards) ; + nbCards = uriList.Count(); for (PRUint32 i = 0 ; i < nbCards ; ++ i) { - cardList->GetElementAt(i, getter_AddRefs(element)) ; - nsVoidKey newKey (NS_STATIC_CAST(void *, element)) ; - nsCOMPtr oldElement = mCardList.Get(&newKey) ; + PRBool isNewCard = PR_FALSE ; - if (!oldElement) { + uriList.CStringAt(i,uriName); + retCode = BuildCardFromURI(uriName,getter_AddRefs(childCard), searchForOldCards, isNewCard); + NS_ENSURE_SUCCESS(retCode, retCode) ; + cardList->AppendElement(childCard); + + if (isNewCard) { // We are dealing with a new element (probably directly // added from Outlook), we may need to sync m_AddressList - mCardList.Put(&newKey, element) ; - nsCOMPtr card (do_QueryInterface(element, &retCode)) ; + nsCStringKey newKey(uriName) ; + + mCardList.Put(&newKey, childCard) ; + nsCOMPtr card (do_QueryInterface(childCard, &retCode)) ; NS_ENSURE_SUCCESS(retCode, retCode) ; PRBool isMailList = PR_FALSE ; @@ -223,18 +259,33 @@ NotifyItemAddition(card) ; } } - else { - NS_ASSERTION(oldElement == element, "Different card stored") ; } } + return cardList->Enumerate(aCards) ; } + +static nsresult ExtractUriFromCard(nsIAbCard *aCard, nsCString& aUri) { + nsresult retCode = NS_OK ; + nsCOMPtr resource (do_QueryInterface(aCard, &retCode)) ; + + // Receiving a non-RDF card is accepted + if (NS_FAILED(retCode)) { return NS_OK ; } + nsXPIDLCString uri ; + + retCode = resource->GetValue(getter_Copies(uri)) ; + NS_ENSURE_SUCCESS(retCode, retCode) ; + aUri = uri.get() ; return retCode ; } NS_IMETHODIMP nsAbOutlookDirectory::HasCard(nsIAbCard *aCard, PRBool *aHasCard) { if (!aCard || !aHasCard) { return NS_ERROR_NULL_POINTER ; } - nsVoidKey key (NS_STATIC_CAST(void *, aCard)) ; + *aHasCard = PR_FALSE ; + nsCString uri ; + + ExtractUriFromCard(aCard, uri) ; + nsCStringKey key(uri) ; *aHasCard = mCardList.Exists(&key) ; return NS_OK ; @@ -309,14 +360,17 @@ NS_ENSURE_SUCCESS(retCode, retCode) ; retCode = ExtractCardEntry(card, entryString) ; - if (NS_SUCCEEDED(retCode) && !entryString.IsEmpty()) { + if (NS_SUCCEEDED(retCode) && entryString.Length() > 0) { cardEntry.Assign(entryString) ; if (!mapiAddBook->DeleteEntry(*mMapiData, cardEntry)) { PRINTF(("Cannot delete card %s.\n", entryString.get())) ; } else { - nsVoidKey key (NS_STATIC_CAST(void *, element)) ; + nsCString uri ; + + ExtractUriFromCard(card, uri) ; + nsCStringKey key(uri) ; mCardList.Remove(&key) ; if (m_IsMailList) { m_AddressList->RemoveElement(element) ; } @@ -336,7 +390,6 @@ return NS_ERROR_NOT_IMPLEMENTED; } - NS_IMETHODIMP nsAbOutlookDirectory::DeleteDirectory(nsIAbDirectory *aDirectory) { if (mIsQueryURI) { return NS_ERROR_NOT_IMPLEMENTED ; } @@ -385,7 +438,10 @@ } retCode = CreateCard(aData, addedCard) ; NS_ENSURE_SUCCESS(retCode, retCode) ; - nsVoidKey newKey (NS_STATIC_CAST(void *, *addedCard)) ; + nsCString uri ; + + ExtractUriFromCard(*addedCard, uri) ; + nsCStringKey newKey(uri) ; mCardList.Put(&newKey, *addedCard) ; if (m_IsMailList) { m_AddressList->AppendElement(*addedCard) ; } @@ -412,7 +468,7 @@ if (!mapiAddBook->IsOK()) { return NS_ERROR_FAILURE ; } retCode = ExtractDirectoryEntry(aMailList, entryString) ; - if (NS_SUCCEEDED(retCode) && !entryString.IsEmpty()) { + if (NS_SUCCEEDED(retCode) && entryString.Length() > 0) { nsMapiEntry sourceEntry ; sourceEntry.Assign(entryString) ; @@ -946,7 +1002,7 @@ *aReturnValue = ++ mCurrentQueryId ; PR_Unlock(mProtector) ; threadArgs->mThreadId = *aReturnValue ; - newThread = PR_CreateThread(PR_USER_THREAD, +/* newThread = PR_CreateThread(PR_USER_THREAD, QueryThreadFunc, threadArgs, PR_PRIORITY_NORMAL, @@ -957,6 +1013,8 @@ delete threadArgs ; return NS_ERROR_OUT_OF_MEMORY ; } +*/ + QueryThreadFunc(threadArgs); nsIntegerKey newKey(*aReturnValue) ; mQueryThreads.Put(&newKey, newThread) ; @@ -1005,16 +1063,10 @@ NS_ENSURE_SUCCESS(retCode, retCode) ; retCode = arguments->SetQuerySubDirectories(PR_TRUE) ; NS_ENSURE_SUCCESS(retCode, retCode) ; - nsCOMPtr proxyListener; - - retCode = NS_GetProxyForObject(NS_UI_THREAD_EVENTQ, - NS_GET_IID(nsIAbDirectoryQueryResultListener), - NS_STATIC_CAST(nsIAbDirectoryQueryResultListener *, new nsAbDirSearchListener(this)), - PROXY_SYNC | PROXY_ALWAYS, - getter_AddRefs(proxyListener)); - NS_ENSURE_SUCCESS(retCode, retCode) ; + nsCOMPtr queryListener ; - return DoQuery(arguments, proxyListener, -1, 0, &mSearchContext) ; + queryListener = new nsAbDirSearchListener(this) ; + return DoQuery(arguments, queryListener, -1, 0, &mSearchContext) ; } NS_IMETHODIMP nsAbOutlookDirectory::StopSearch(void) @@ -1031,7 +1083,10 @@ nsresult nsAbOutlookDirectory::OnSearchFoundCard(nsIAbCard *aCard) { - nsVoidKey newKey (NS_STATIC_CAST(void *, aCard)) ; + nsCString uri ; + + ExtractUriFromCard(aCard, uri) ; + nsCStringKey newKey(uri) ; nsresult retCode = NS_OK ; mCardList.Put(&newKey, aCard) ; @@ -1055,14 +1110,14 @@ retCode = BuildRestriction(aArguments, arguments) ; NS_ENSURE_SUCCESS(retCode, retCode) ; nsCOMPtr resultsArray ; + nsCStringArray uriArray ; PRUint32 nbResults = 0 ; - retCode = GetChildCards(getter_AddRefs(resultsArray), + retCode = GetChildCards(uriArray, arguments.rt == RES_COMMENT ? nsnull : &arguments) ; DestroyRestriction(arguments) ; NS_ENSURE_SUCCESS(retCode, retCode) ; - retCode = resultsArray->Count(&nbResults) ; - NS_ENSURE_SUCCESS(retCode, retCode) ; + nbResults = uriArray.Count() ; nsCOMPtr result ; nsAbDirectoryQueryResult *newResult = nsnull ; @@ -1070,15 +1125,18 @@ nbResults = NS_STATIC_CAST(PRUint32, aResultLimit) ; } PRUint32 i = 0 ; - nsCOMPtr element ; nsCOMPtr propertyValues ; + nsCAutoString uriName; + nsCOMPtr card; + for (i = 0 ; i < nbResults ; ++ i) { - retCode = resultsArray->GetElementAt(i, getter_AddRefs(element)) ; - NS_ENSURE_SUCCESS(retCode, retCode) ; - nsCOMPtr card (do_QueryInterface(element, &retCode)) ; + PRBool isNewCard = PR_FALSE ; + uriArray.CStringAt(i,uriName); + retCode = BuildCardFromURI(uriName,getter_AddRefs(card), PR_FALSE, isNewCard); NS_ENSURE_SUCCESS(retCode, retCode) ; + FillPropertyValues(card, aArguments, getter_AddRefs(propertyValues)) ; newResult = new nsAbDirectoryQueryResult(0, aArguments, nsIAbDirectoryQueryResult::queryResultMatch, @@ -1103,6 +1161,38 @@ if (!aCards) { return NS_ERROR_NULL_POINTER ; } *aCards = nsnull ; nsresult retCode = NS_OK ; + + nsCOMPtr cards; + retCode = NS_NewISupportsArray(getter_AddRefs(cards)); + NS_ENSURE_SUCCESS(retCode, retCode) ; + + nsCStringArray uriList; + retCode = GetChildCards(uriList,aRestriction); + NS_ENSURE_SUCCESS(retCode, retCode) ; + + nsCAutoString uriName; + nsCOMPtr childCard; + PRUint32 nbURIs = 0 ; + nbURIs = uriList.Count(); + PRUint32 i = 0 ; + + for (i = 0 ; i < nbURIs ; ++ i) { + PRBool isNewCard = PR_FALSE ; + + uriList.CStringAt(i,uriName); + retCode = BuildCardFromURI(uriName,getter_AddRefs(childCard), PR_TRUE, isNewCard); + NS_ENSURE_SUCCESS(retCode, retCode) ; + cards->AppendElement(childCard); + } + + NS_IF_ADDREF(*aCards = cards); + return retCode ; +} + +nsresult nsAbOutlookDirectory::GetChildCards(nsCStringArray& aURI, + void *aRestriction) +{ + nsresult retCode = NS_OK ; nsCOMPtr cards ; nsAbWinHelperGuard mapiAddBook (mAbWinType) ; nsMapiEntryArray cardEntries ; @@ -1117,23 +1207,14 @@ } nsCAutoString entryId ; nsCAutoString uriName ; - nsCOMPtr resource ; - nsCOMPtr childCard; + aURI.Clear(); - for (ULONG card = 0 ; card < cardEntries.mNbEntries ; ++ card) { - cardEntries.mEntries [card].ToString(entryId) ; + for (ULONG card = 0 ; card < cardEntries.GetSize() ; ++ card) { + cardEntries [card].ToString(entryId) ; buildAbWinUri(kOutlookCardScheme, mAbWinType, uriName) ; uriName.Append(entryId) ; - childCard = do_CreateInstance(NS_ABOUTLOOKCARD_CONTRACTID, &retCode); - NS_ENSURE_SUCCESS(retCode, retCode) ; - resource = do_QueryInterface(childCard, &retCode) ; - NS_ENSURE_SUCCESS(retCode, retCode) ; - retCode = resource->Init(uriName.get()) ; - NS_ENSURE_SUCCESS(retCode, retCode) ; - cards->AppendElement(childCard) ; + aURI.AppendCString(uriName); } - *aCards = cards ; - NS_ADDREF(*aCards) ; return retCode ; } @@ -1157,8 +1238,8 @@ nsCAutoString uriName ; nsCOMPtr resource ; - for (ULONG node = 0 ; node < nodeEntries.mNbEntries ; ++ node) { - nodeEntries.mEntries [node].ToString(entryId) ; + for (ULONG node = 0 ; node < nodeEntries.GetSize() ; ++ node) { + nodeEntries [node].ToString(entryId) ; buildAbWinUri(kOutlookDirectoryScheme, mAbWinType, uriName) ; uriName.Append(entryId) ; retCode = gRDFService->GetResource(uriName, getter_AddRefs(resource)) ; @@ -1234,7 +1315,8 @@ nsresult retCode = S_OK ; if (m_IsMailList) { - retCode = GetChildCards(getter_AddRefs(m_AddressList), nsnull) ; + //retCode = GetChildCards(getter_AddRefs(m_AddressList), nsnull) ; + //retCode = GetChildNodes(getter_AddRefs(m_AddressList)) ; } else { retCode = GetChildNodes(getter_AddRefs(m_AddressList)) ; @@ -1256,7 +1338,7 @@ // If we get a RDF resource and it maps onto an Outlook card uri, // we simply copy the contents of the Outlook card. retCode = ExtractCardEntry(aData, entryString) ; - if (NS_SUCCEEDED(retCode) && !entryString.IsEmpty()) { + if (NS_SUCCEEDED(retCode) && entryString.Length() > 0) { nsMapiEntry sourceEntry ; Index: addrbook/src/nsAbOutlookDirectory.h =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsAbOutlookDirectory.h,v retrieving revision 1.5 diff -u -w -b -i -r1.5 nsAbOutlookDirectory.h --- addrbook/src/nsAbOutlookDirectory.h 5 Mar 2003 02:49:16 -0000 1.5 +++ addrbook/src/nsAbOutlookDirectory.h 18 Sep 2003 09:03:13 -0000 @@ -46,6 +46,7 @@ #include "nsHashtable.h" #include "nsISupportsArray.h" +#include "nsVoidArray.h" struct nsMapiEntry ; @@ -92,6 +93,8 @@ protected: // Retrieve hierarchy as cards, with an optional restriction nsresult GetChildCards(nsISupportsArray **aCards, void *aRestriction) ; + // Retrieve hierarchy as URIs, with an optional restriction + nsresult GetChildCards(nsCStringArray& aURI, void *aRestriction) ; // Retrieve hierarchy as directories nsresult GetChildNodes(nsISupportsArray **aNodes) ; // Create a new card @@ -103,6 +106,9 @@ nsresult CommitAddressList(void) ; // Read MAPI repository nsresult UpdateAddressList(void) ; + // Search for an existing card or build a new one + nsresult BuildCardFromURI(const nsCString& uriName,nsIAbCard **aNewCard, + PRBool aSearchForOld, PRBool& aIsNewCard) ; nsMapiEntry *mMapiData ; // Container for the query threads Index: addrbook/src/nsAbWinHelper.cpp =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsAbWinHelper.cpp,v retrieving revision 1.11 diff -u -w -b -i -r1.11 nsAbWinHelper.cpp --- addrbook/src/nsAbWinHelper.cpp 16 Sep 2002 12:33:22 -0000 1.11 +++ addrbook/src/nsAbWinHelper.cpp 18 Sep 2003 09:03:13 -0000 @@ -41,6 +41,7 @@ #define USES_IID_IABContainer #define USES_IID_IMAPITable #define USES_IID_IDistList +#define USES_IID_IMsgStore #include "nsAbWinHelper.h" #include "nsAbUtils.h" @@ -59,19 +60,6 @@ #define PRINTF(args) PR_LOG(gAbWinHelperLog, PR_LOG_DEBUG, args) -// Small utility to ensure release of all MAPI interfaces -template struct nsMapiInterfaceWrapper -{ - tInterface mInterface ; - - nsMapiInterfaceWrapper(void) : mInterface(NULL) {} - ~nsMapiInterfaceWrapper(void) { - if (mInterface != NULL) { mInterface->Release() ; } - } - operator LPUNKNOWN *(void) { return NS_REINTERPRET_CAST(LPUNKNOWN *, &mInterface) ; } - tInterface operator -> (void) const { return mInterface ; } - operator tInterface *(void) { return &mInterface ; } -} ; static void assignEntryID(LPENTRYID& aTarget, LPENTRYID aSource, ULONG aByteCount) { @@ -249,24 +237,28 @@ MOZ_DECL_CTOR_COUNTER(nsMapiEntryArray) nsMapiEntryArray::nsMapiEntryArray(void) -: mEntries(NULL), mNbEntries(0) { MOZ_COUNT_CTOR(nsMapiEntryArray) ; } nsMapiEntryArray::~nsMapiEntryArray(void) { - if (mEntries) { delete [] mEntries ; } + CleanUp(); MOZ_COUNT_DTOR(nsMapiEntryArray) ; } - +void nsMapiEntryArray::AddItem(nsMapiEntry * aEntries) +{ + m_array.AppendElement(aEntries); +} void nsMapiEntryArray::CleanUp(void) { - if (mEntries != NULL) { - delete [] mEntries ; - mEntries = NULL ; - mNbEntries = 0 ; + nsMapiEntry *pEntries; + for (int i = 0; i < m_array.Count(); i++) + { + pEntries = (nsMapiEntry *)m_array.ElementAt( i); + delete pEntries; } + m_array.Clear(); } MOZ_DECL_CTOR_COUNTER(nsAbWinHelper) @@ -281,7 +273,7 @@ PRLock *nsAbWinHelper::mMutex = PR_NewLock() ; nsAbWinHelper::nsAbWinHelper(void) -: mAddressBook(NULL), mLastError(S_OK) +:mLastError(S_OK) { MOZ_COUNT_CTOR(nsAbWinHelper) ; } @@ -291,89 +283,26 @@ MOZ_COUNT_DTOR(nsAbWinHelper) ; } -BOOL nsAbWinHelper::GetFolders(nsMapiEntryArray& aFolders) -{ - aFolders.CleanUp() ; - nsMapiInterfaceWrapper rootFolder ; - nsMapiInterfaceWrapper folders ; - ULONG objType = 0 ; - ULONG rowCount = 0 ; - SRestriction restriction ; - SPropTagArray folderColumns ; - - mLastError = mAddressBook->OpenEntry(0, NULL, NULL, 0, &objType, - rootFolder) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot open root %08x.\n", mLastError)) ; - return FALSE ; - } - mLastError = rootFolder->GetHierarchyTable(0, folders) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot get hierarchy %08x.\n", mLastError)) ; - return FALSE ; - } - // We only take into account modifiable containers, - // otherwise, we end up with all the directory services... - restriction.rt = RES_BITMASK ; - restriction.res.resBitMask.ulPropTag = PR_CONTAINER_FLAGS ; - restriction.res.resBitMask.relBMR = BMR_NEZ ; - restriction.res.resBitMask.ulMask = AB_MODIFIABLE ; - mLastError = folders->Restrict(&restriction, 0) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot restrict table %08x.\n", mLastError)) ; - } - folderColumns.cValues = 1 ; - folderColumns.aulPropTag [0] = PR_ENTRYID ; - mLastError = folders->SetColumns(&folderColumns, 0) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot set columns %08x.\n", mLastError)) ; - return FALSE ; - } - mLastError = folders->GetRowCount(0, &rowCount) ; - if (HR_SUCCEEDED(mLastError)) { - aFolders.mEntries = new nsMapiEntry [rowCount] ; - aFolders.mNbEntries = 0 ; - do { - LPSRowSet rowSet = NULL ; - - rowCount = 0 ; - mLastError = folders->QueryRows(1, 0, &rowSet) ; - if (HR_SUCCEEDED(mLastError)) { - rowCount = rowSet->cRows ; - if (rowCount > 0) { - nsMapiEntry& current = aFolders.mEntries [aFolders.mNbEntries ++] ; - SPropValue& currentValue = rowSet->aRow->lpProps [0] ; - - current.Assign(currentValue.Value.bin.cb, - NS_REINTERPRET_CAST(LPENTRYID, currentValue.Value.bin.lpb)) ; - } - MyFreeProws(rowSet) ; - } - else { - PRINTF(("Cannot query rows %08x.\n", mLastError)) ; - } - } while (rowCount > 0) ; - } - return HR_SUCCEEDED(mLastError) ; -} BOOL nsAbWinHelper::GetCards(const nsMapiEntry& aParent, LPSRestriction aRestriction, nsMapiEntryArray& aCards) { aCards.CleanUp() ; - return GetContents(aParent, aRestriction, &aCards.mEntries, aCards.mNbEntries, 0) ; + return GetContents(aParent, aRestriction, &aCards, 0) ; } BOOL nsAbWinHelper::GetNodes(const nsMapiEntry& aParent, nsMapiEntryArray& aNodes) { aNodes.CleanUp() ; - return GetContents(aParent, NULL, &aNodes.mEntries, aNodes.mNbEntries, MAPI_DISTLIST) ; + return GetContents(aParent, NULL, &aNodes, MAPI_DISTLIST) ; } BOOL nsAbWinHelper::GetCardsCount(const nsMapiEntry& aParent, ULONG& aNbCards) { - aNbCards = 0 ; - return GetContents(aParent, NULL, NULL, aNbCards, 0) ; + nsMapiEntryArray aCards; + BOOL ret=GetContents(aParent, NULL, &aCards, 0) ; + aNbCards=aCards.GetSize(); + return ret; } BOOL nsAbWinHelper::GetPropertyString(const nsMapiEntry& aObject, @@ -431,7 +360,11 @@ ULONG i = 0 ; for (i = 0 ; i < valueCount ; ++ i) { - if (PROP_ID(values [i].ulPropTag) == PROP_ID(aPropertyTags [i])) { + + if (PROP_TYPE( values [i].ulPropTag) != PT_ERROR && values [i].Value.l != MAPI_E_NOT_FOUND) + { + //if (PROP_ID(values [i].ulPropTag) == PROP_ID(aPropertyTags [i])) + //{ if (PROP_TYPE(values [i].ulPropTag) == PT_STRING8) { nsAutoString temp ; @@ -441,6 +374,15 @@ else if (PROP_TYPE(values [i].ulPropTag) == PT_UNICODE) { aNames.AppendString(nsAutoString (values [i].Value.lpszW)) ; } + else if (aPropertyTags [i] == PR_EMAIL_ADDRESS_A) { + nsAutoString temp ; + + temp.AssignWithConversion (values [i].Value.lpszA) ; + aNames.AppendString(temp) ; + } + else if (aPropertyTags [i] == PR_EMAIL_ADDRESS_W) { + aNames.AppendString(nsAutoString (values [i].Value.lpszW)) ; + } else { aNames.AppendString(nsAutoString((const PRUnichar *) "")) ; } @@ -518,7 +460,7 @@ nsMapiInterfaceWrapper subObject ; ULONG objType = 0 ; - mLastError = mAddressBook->OpenEntry(aContainer.mByteCount, aContainer.mEntryId, + mLastError = OpenEntry(aContainer.mByteCount, aContainer.mEntryId, &IID_IMAPIContainer, 0, &objType, container) ; if (HR_FAILED(mLastError)) { @@ -537,7 +479,7 @@ SBinary entry ; SBinaryArray entryArray ; - mLastError = mAddressBook->OpenEntry(aContainer.mByteCount, aContainer.mEntryId, + mLastError = OpenEntry(aContainer.mByteCount, aContainer.mEntryId, &IID_IABContainer, MAPI_MODIFY, &objType, container) ; if (HR_FAILED(mLastError)) { @@ -636,7 +578,7 @@ nsMapiInterfaceWrapper container ; ULONG objType = 0 ; - mLastError = mAddressBook->OpenEntry(aParent.mByteCount, aParent.mEntryId, + mLastError = OpenEntry(aParent.mByteCount, aParent.mEntryId, &IID_IABContainer, MAPI_MODIFY, &objType, container) ; if (HR_FAILED(mLastError)) { @@ -699,7 +641,7 @@ nsMapiInterfaceWrapper container ; ULONG objType = 0 ; - mLastError = mAddressBook->OpenEntry(aParent.mByteCount, aParent.mEntryId, + mLastError = OpenEntry(aParent.mByteCount, aParent.mEntryId, &IID_IABContainer, MAPI_MODIFY, &objType, container) ; if (HR_FAILED(mLastError)) { @@ -764,7 +706,7 @@ nsMapiInterfaceWrapper container ; ULONG objType = 0 ; - mLastError = mAddressBook->OpenEntry(aContainer.mByteCount, aContainer.mEntryId, + mLastError = OpenEntry(aContainer.mByteCount, aContainer.mEntryId, &IID_IABContainer, MAPI_MODIFY, &objType, container) ; if (HR_FAILED(mLastError)) { @@ -801,194 +743,46 @@ return TRUE ; } -BOOL nsAbWinHelper::GetDefaultContainer(nsMapiEntry& aContainer) -{ - LPENTRYID entryId = NULL ; - ULONG byteCount = 0 ; - - mLastError = mAddressBook->GetPAB(&byteCount, &entryId) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot get PAB %08x.\n", mLastError)) ; - return FALSE ; - } - aContainer.Assign(byteCount, entryId) ; - FreeBuffer(entryId) ; - return TRUE ; -} - -enum -{ - ContentsColumnEntryId = 0, - ContentsColumnObjectType, - ContentsColumnsSize -} ; - -static const SizedSPropTagArray(ContentsColumnsSize, ContentsColumns) = -{ - ContentsColumnsSize, - { - PR_ENTRYID, - PR_OBJECT_TYPE - } -} ; - -BOOL nsAbWinHelper::GetContents(const nsMapiEntry& aParent, LPSRestriction aRestriction, - nsMapiEntry **aList, ULONG& aNbElements, ULONG aMapiType) -{ - if (aList != NULL) { *aList = NULL ; } - aNbElements = 0 ; - nsMapiInterfaceWrapper parent ; - nsMapiInterfaceWrapper contents ; - ULONG objType = 0 ; - ULONG rowCount = 0 ; - - mLastError = mAddressBook->OpenEntry(aParent.mByteCount, aParent.mEntryId, - &IID_IMAPIContainer, 0, &objType, - parent) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot open parent %08x.\n", mLastError)) ; - return FALSE ; - } - // Here, flags for WAB and MAPI could be different, so this works - // only as long as we don't want to use any flag in GetContentsTable - mLastError = parent->GetContentsTable(0, contents) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot get contents %08x.\n", mLastError)) ; - return FALSE ; - } - if (aRestriction != NULL) { - mLastError = contents->Restrict(aRestriction, 0) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot set restriction %08x.\n", mLastError)) ; - return FALSE ; - } - } - mLastError = contents->SetColumns((LPSPropTagArray) &ContentsColumns, 0) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot set columns %08x.\n", mLastError)) ; - return FALSE ; - } - mLastError = contents->GetRowCount(0, &rowCount) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot get result count %08x.\n", mLastError)) ; - return FALSE ; - } - if (aList != NULL) { *aList = new nsMapiEntry [rowCount] ; } - aNbElements = 0 ; - do { - LPSRowSet rowSet = NULL ; - rowCount = 0 ; - mLastError = contents->QueryRows(1, 0, &rowSet) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot query rows %08x.\n", mLastError)) ; - return FALSE ; - } - rowCount = rowSet->cRows ; - if (rowCount > 0 && - (aMapiType == 0 || - rowSet->aRow->lpProps[ContentsColumnObjectType].Value.ul == aMapiType)) { - if (aList != NULL) { - nsMapiEntry& current = (*aList) [aNbElements] ; - SPropValue& currentValue = rowSet->aRow->lpProps[ContentsColumnEntryId] ; - current.Assign(currentValue.Value.bin.cb, - NS_REINTERPRET_CAST(LPENTRYID, currentValue.Value.bin.lpb)) ; - } - ++ aNbElements ; - } - MyFreeProws(rowSet) ; - } while (rowCount > 0) ; - return TRUE ; -} -BOOL nsAbWinHelper::GetMAPIProperties(const nsMapiEntry& aObject, const ULONG *aPropertyTags, - ULONG aNbProperties, LPSPropValue& aValue, - ULONG& aValueCount) +void nsAbWinHelper::MyFreeProws(LPSRowSet aRowset) { - nsMapiInterfaceWrapper object ; - ULONG objType = 0 ; - LPSPropTagArray properties = NULL ; + if (aRowset == NULL) { return ; } ULONG i = 0 ; - mLastError = mAddressBook->OpenEntry(aObject.mByteCount, aObject.mEntryId, - &IID_IMAPIProp, 0, &objType, - object) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot open entry %08x.\n", mLastError)) ; - return FALSE ; - } - AllocateBuffer(CbNewSPropTagArray(aNbProperties), - NS_REINTERPRET_CAST(void **, &properties)) ; - properties->cValues = aNbProperties ; - for (i = 0 ; i < aNbProperties ; ++ i) { - properties->aulPropTag [i] = aPropertyTags [i] ; - } - mLastError = object->GetProps(properties, 0, &aValueCount, &aValue) ; - FreeBuffer(properties) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot get props %08x.\n", mLastError)) ; + for (i = 0 ; i < aRowset->cRows ; ++ i) { + FreeBuffer(aRowset->aRow [i].lpProps) ; } - return HR_SUCCEEDED(mLastError) ; + FreeBuffer(aRowset) ; } -BOOL nsAbWinHelper::SetMAPIProperties(const nsMapiEntry& aObject, ULONG aNbProperties, - const LPSPropValue& aValues) -{ - nsMapiInterfaceWrapper object ; - ULONG objType = 0 ; - LPSPropProblemArray problems = NULL ; +static nsAbWinHelper *getOutlookAddressBook(void) { + static nsMapiAddressBook *addressBook = NULL ; - mLastError = mAddressBook->OpenEntry(aObject.mByteCount, aObject.mEntryId, - &IID_IMAPIProp, MAPI_MODIFY, &objType, - object) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot open entry %08x.\n", mLastError)) ; - return FALSE ; - } - mLastError = object->SetProps(aNbProperties, aValues, &problems) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot update the object %08x.\n", mLastError)) ; - return FALSE ; - } - if (problems != NULL) { - for (ULONG i = 0 ; i < problems->cProblem ; ++ i) { - PRINTF(("Problem %d: index %d code %08x.\n", i, - problems->aProblem [i].ulIndex, - problems->aProblem [i].scode)) ; - } - } - mLastError = object->SaveChanges(0) ; - if (HR_FAILED(mLastError)) { - PRINTF(("Cannot commit changes %08x.\n", mLastError)) ; - } - return HR_SUCCEEDED(mLastError) ; + if (addressBook == NULL) { addressBook = new nsMapiAddressBook ; } + return addressBook ; } -void nsAbWinHelper::MyFreeProws(LPSRowSet aRowset) -{ - if (aRowset == NULL) { return ; } - ULONG i = 0 ; +static nsAbWinHelper *getOutlookExpAddressBook(void) { + static nsWabAddressBook *addressBook = NULL ; - for (i = 0 ; i < aRowset->cRows ; ++ i) { - FreeBuffer(aRowset->aRow [i].lpProps) ; - } - FreeBuffer(aRowset) ; + if (addressBook == NULL) { addressBook = new nsWabAddressBook ; } + return addressBook ; } nsAbWinHelperGuard::nsAbWinHelperGuard(PRUint32 aType) : mHelper(NULL) { switch(aType) { - case nsAbWinType_Outlook: mHelper = new nsMapiAddressBook ; break ; - case nsAbWinType_OutlookExp: mHelper = new nsWabAddressBook ; break ; + case nsAbWinType_Outlook: mHelper = getOutlookAddressBook() ; break ; + case nsAbWinType_OutlookExp: mHelper = getOutlookExpAddressBook() ; break ; default: break ; } } nsAbWinHelperGuard::~nsAbWinHelperGuard(void) { - delete mHelper ; } const char *kOutlookDirectoryScheme = "moz-aboutlookdirectory://" ; Index: addrbook/src/nsAbWinHelper.h =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsAbWinHelper.h,v retrieving revision 1.2 diff -u -w -b -i -r1.2 nsAbWinHelper.h --- addrbook/src/nsAbWinHelper.h 28 Sep 2001 20:06:23 -0000 1.2 +++ addrbook/src/nsAbWinHelper.h 18 Sep 2003 09:03:14 -0000 @@ -45,6 +45,21 @@ #include "nsVoidArray.h" #include "nsXPIDLString.h" + +// Small utility to ensure release of all MAPI interfaces +template struct nsMapiInterfaceWrapper +{ + tInterface mInterface ; + + nsMapiInterfaceWrapper(void) : mInterface(NULL) {} + ~nsMapiInterfaceWrapper(void) { + if (mInterface != NULL) { mInterface->Release() ; } + } + operator LPUNKNOWN *(void) { return NS_REINTERPRET_CAST(LPUNKNOWN *, &mInterface) ; } + tInterface operator -> (void) const { return mInterface ; } + operator tInterface *(void) { return &mInterface ; } +} ; + struct nsMapiEntry { ULONG mByteCount ; @@ -62,14 +77,26 @@ struct nsMapiEntryArray { - nsMapiEntry *mEntries ; - ULONG mNbEntries ; + //nsMapiEntry *mEntries ; + //ULONG mNbEntries ; nsMapiEntryArray(void) ; ~nsMapiEntryArray(void) ; - const nsMapiEntry& operator [] (int aIndex) const { return mEntries [aIndex] ; } + void AddItem(nsMapiEntry * aEntries); + void AddItem( ULONG mByteCount , LPENTRYID mEntryId ) + { + nsMapiEntry * aEntries=new nsMapiEntry(); + aEntries->Assign(mByteCount,mEntryId); + AddItem(aEntries); + } + + ULONG GetSize( void) { return( m_array.Count());} + const nsMapiEntry& operator [] (int aIndex) const { return *(nsMapiEntry*)m_array.ElementAt(aIndex); } void CleanUp(void) ; +private: + nsVoidArray m_array; + } ; class nsAbWinHelper @@ -79,7 +106,7 @@ virtual ~nsAbWinHelper(void) ; // Get the top address books - BOOL GetFolders(nsMapiEntryArray& aFolders) ; + virtual BOOL GetFolders(nsMapiEntryArray& aFolders) =0; // Get a list of entries for cards/mailing lists in a folder/mailing list BOOL GetCards(const nsMapiEntry& aParent, LPSRestriction aRestriction, nsMapiEntryArray& aCards) ; @@ -99,8 +126,6 @@ // Get the value of a MAPI property of type SYSTIME BOOL GetPropertyDate(const nsMapiEntry& aObject, ULONG aPropertyTag, WORD& aYear, WORD& aMonth, WORD& aDay) ; - // Get the value of a MAPI property of type LONG - BOOL GetPropertyLong(const nsMapiEntry& aObject, ULONG aPropertyTag, ULONG& aValue) ; // Get the value of a MAPI property of type BIN BOOL GetPropertyBin(const nsMapiEntry& aObject, ULONG aPropertyTag, nsMapiEntry& aValue) ; // Tests if a container contains an entry @@ -123,26 +148,46 @@ // Copy an existing entry in the address book BOOL CopyEntry(const nsMapiEntry& aContainer, const nsMapiEntry& aSource, nsMapiEntry& aTarget) ; // Get a default address book container - BOOL GetDefaultContainer(nsMapiEntry& aContainer) ; + virtual BOOL GetDefaultContainer(nsMapiEntry& aContainer) =0; // Is the helper correctly initialised? - BOOL IsOK(void) const { return mAddressBook != NULL ; } + virtual BOOL IsOK(void) =0;/*const { return mAddressBook != NULL ; }*/ + + // Get the value of a MAPI property of type LONG + virtual BOOL GetPropertyLong(const nsMapiEntry& aObject, ULONG aPropertyTag, ULONG& aValue) ; protected: HRESULT mLastError ; - LPADRBOOK mAddressBook ; static ULONG mEntryCounter ; static PRLock *mMutex ; + virtual HRESULT OpenEntry(ULONG cbEntryID, + LPENTRYID lpEntryID, + LPCIID lpInterface, + ULONG ulFlags, + ULONG FAR * lpulObjType, + LPUNKNOWN FAR * lppUnk + ) = 0; + /* + { + return mAddressBook->OpenEntry(cbEntryID, + lpEntryID, + lpInterface, + ulFlags, + lpulObjType, + lppUnk + ); + } + */ // Retrieve the contents of a container, with an optional restriction - BOOL GetContents(const nsMapiEntry& aParent, LPSRestriction aRestriction, - nsMapiEntry **aList, ULONG &aNbElements, ULONG aMapiType) ; + virtual BOOL GetContents(const nsMapiEntry& aParent, LPSRestriction aRestriction, + nsMapiEntryArray *aList, ULONG aMapiType) =0; // Retrieve the values of a set of properties on a MAPI object - BOOL GetMAPIProperties(const nsMapiEntry& aObject, const ULONG *aPropertyTags, + virtual BOOL GetMAPIProperties(const nsMapiEntry& aObject, const ULONG *aPropertyTags, ULONG aNbProperties, - LPSPropValue& aValues, ULONG& aValueCount) ; + LPSPropValue& aValues, ULONG& aValueCount) =0; // Set the values of a set of properties on a MAPI object - BOOL SetMAPIProperties(const nsMapiEntry& aObject, ULONG aNbProperties, - const LPSPropValue& aValues) ; + virtual BOOL SetMAPIProperties(const nsMapiEntry& aObject, ULONG aNbProperties, + const LPSPropValue& aValues) =0; // Clean-up a rowset returned by QueryRows void MyFreeProws(LPSRowSet aSet) ; // Allocation of a buffer for transmission to interfaces @@ -166,7 +211,10 @@ nsAbWinHelperGuard(PRUint32 aType) ; ~nsAbWinHelperGuard(void) ; - nsAbWinHelper *operator ->(void) { return mHelper ; } + nsAbWinHelper *operator ->(void) + { + return mHelper ; + } private: nsAbWinHelper *mHelper ; Index: addrbook/src/nsMapiAddressBook.cpp =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsMapiAddressBook.cpp,v retrieving revision 1.7 diff -u -w -b -i -r1.7 nsMapiAddressBook.cpp --- addrbook/src/nsMapiAddressBook.cpp 30 Oct 2001 07:59:16 -0000 1.7 +++ addrbook/src/nsMapiAddressBook.cpp 18 Sep 2003 09:03:14 -0000 @@ -47,7 +47,48 @@ #endif #define PRINTF(args) PR_LOG(gMapiAddressBookLog, PR_LOG_DEBUG, args) +#define OUTLOOK_EMAIL1_MAPI_ID1 32899 +enum { + ieidPR_ENTRYID = 0, + ieidPR_OBJECT_TYPE, + ieidPR_DISPLAY_NAME, + ieidPR_MESSAGE_CLASS, + ieidPR_STORE_ENTRYID, + ieidPR_MESSAGE_RECIPIENTS, + ieidMax +}; + +static const SizedSPropTagArray(ieidMax, ptaEid)= +{ + ieidMax, + { + PR_ENTRYID, + PR_OBJECT_TYPE, + PR_DISPLAY_NAME, + PR_MESSAGE_CLASS, + PR_STORE_ENTRYID, + PR_MESSAGE_RECIPIENTS + } +}; + +enum +{ + ContentsColumnEntryId = 0, + ContentsColumnObjectType, + ContentsColumnMessageClass, + ContentsColumnsSize +} ; + +static const SizedSPropTagArray(ContentsColumnsSize, ContentsColumns) = +{ + ContentsColumnsSize, + { + PR_ENTRYID, + PR_OBJECT_TYPE, + PR_MESSAGE_CLASS + } +} ; HMODULE nsMapiAddressBook::mLibrary = NULL ; PRInt32 nsMapiAddressBook::mLibUsage = 0 ; @@ -60,7 +101,7 @@ BOOL nsMapiAddressBook::mInitialized = FALSE ; BOOL nsMapiAddressBook::mLogonDone = FALSE ; LPMAPISESSION nsMapiAddressBook::mRootSession = NULL ; -LPADRBOOK nsMapiAddressBook::mRootBook = NULL ; +LPMAPISESSION nsMapiAddressBook::mRootBook = NULL ; BOOL nsMapiAddressBook::LoadMapiLibrary(void) { @@ -109,10 +150,12 @@ PRINTF(("Cannot logon to MAPI %08x.\n", retCode)) ; return FALSE ; } mLogonDone = TRUE ; - retCode = mRootSession->OpenAddressBook(0, NULL, 0, &mRootBook) ; - if (HR_FAILED(retCode)) { - PRINTF(("Cannot open MAPI address book %08x.\n", retCode)) ; - } + + //retCode = mRootSession->OpenAddressBook(0, NULL, 0, &mRootBook) ; + //if (HR_FAILED(retCode)) { + // PRINTF(("Cannot open MAPI address book %08x.\n", retCode)) ; + //} + mRootBook = mRootSession; return HR_SUCCEEDED(retCode) ; } @@ -121,7 +164,7 @@ if (mLibrary) { if (-- mLibUsage == 0) { { - if (mRootBook) { mRootBook->Release() ; } + //if (mRootBook) { mRootBook->Release() ; } if (mRootSession) { if (mLogonDone) { mRootSession->Logoff(NULL, 0, 0) ; @@ -159,16 +202,552 @@ MOZ_COUNT_DTOR(nsMapiAddressBook) ; } +LPSPropValue nsMapiAddressBook::GetMapiProperty( LPMAPIPROP pProp, ULONG tag) +{ + if (!pProp) + return( NULL); + + int sz = CbNewSPropTagArray( 1); + SPropTagArray *pTag = (SPropTagArray *) new char[sz]; + pTag->cValues = 1; + pTag->aulPropTag[0] = tag; + LPSPropValue lpProp = NULL; + ULONG cValues = 0; + HRESULT hr = pProp->GetProps( pTag, 0, &cValues, &lpProp); + delete pTag; + if (HR_FAILED( hr) || (cValues != 1)) { + if (lpProp) + mMAPIFreeBuffer( lpProp); + return( NULL); + } + else { + if (PROP_TYPE( lpProp->ulPropTag) == PT_ERROR) { + if (lpProp->Value.l == MAPI_E_NOT_FOUND) { + mMAPIFreeBuffer( lpProp); + lpProp = NULL; + } + } + } + + return( lpProp); +} +BOOL nsMapiAddressBook::GetEntryIdFromProp( LPSPropValue pVal, ULONG& cbEntryId, LPENTRYID& lpEntryId, BOOL delVal) +{ + if (!pVal) + return( FALSE); + + BOOL bResult = TRUE; + switch( PROP_TYPE( pVal->ulPropTag)) { + case PT_BINARY: + cbEntryId = pVal->Value.bin.cb; + mMAPIAllocateBuffer( cbEntryId, (LPVOID *) &lpEntryId); + memcpy( lpEntryId, pVal->Value.bin.lpb, cbEntryId); + break; + + default: + //MAPI_TRACE0( "EntryId not in BINARY prop value\n"); + bResult = FALSE; + break; + } + + if (pVal && delVal) + mMAPIFreeBuffer( pVal); + + return( bResult); +} + +BOOL nsMapiAddressBook::HandleContentsItem(ULONG oType, ULONG cb, LPENTRYID pEntry,nsMapiEntryArray& aFolders) +{ + IMsgStore * store=NULL; + ULONG objType=0; + HRESULT hr; + + if (oType == MAPI_MESSAGE) + { +// GetMAPIProperties(cb, +// pEntry +// ); + } + else + if (oType == MAPI_STORE) + { + hr=OpenEntry( + cb, + pEntry, + &IID_IMsgStore, + 0, + &objType, + (LPUNKNOWN *)&store); + if (FAILED(hr)) + { + return FALSE; + } + LPSPropValue pVal; + pVal=GetMapiProperty(store,PR_IPM_SUBTREE_ENTRYID); + + if (pVal) { + ULONG cbEntry; + LPENTRYID pEntry; + IABContainer * lpSubTree = NULL; + + if (GetEntryIdFromProp( pVal, cbEntry, pEntry)) { + // Open up the folder! + BOOL bResult = TRUE; + bResult = store->OpenEntry( + cbEntry, + pEntry, + NULL, + 0, + &objType, + (LPUNKNOWN *)&lpSubTree); + mMAPIFreeBuffer( pEntry); + if (!bResult && lpSubTree) { + // Iterate the subtree with the results going into the folder list +// CGetStoreFoldersIter iterHandler( this, folders, startDepth); + bResult = IterateHierarchy(lpSubTree,aFolders); + lpSubTree->Release(); + } + else { + //MAPI_TRACE0( "GetStoreFolders: Error opening sub tree.\n"); + } + } + else { + //MAPI_TRACE0( "GetStoreFolders: Error getting entryID from sub tree property val.\n"); + } + } + else { + //MAPI_TRACE0( "GetStoreFolders: Error getting sub tree property.\n"); + } + } + else + { + printf("Type:%d\n",oType); + } + + return TRUE; +} + +BOOL nsMapiAddressBook::IterateHierarchy(IMAPIContainer * pFolder,nsMapiEntryArray& aFolders, ULONG flags) +{ + // flags can be CONVENIENT_DEPTH or 0 + // CONVENIENT_DEPTH will return all depths I believe instead + // of just children + HRESULT hr; + LPMAPITABLE lpTable; + hr = pFolder->GetHierarchyTable( CONVENIENT_DEPTH , &lpTable); + if (HR_FAILED(hr)) { + //MAPI_TRACE2( "IterateHierarchy: GetContentsTable failed: 0x%lx, %d\n", (long)hr, (int)hr); + return( FALSE); + } + + ULONG rowCount; + hr = lpTable->GetRowCount( 0, &rowCount); + if (!rowCount) { + lpTable->Release(); + return( TRUE); + } + + hr = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0); + if (HR_FAILED(hr)) { + lpTable->Release(); + //MAPI_TRACE2( "IterateHierarchy: SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr); + return( FALSE); + } + + hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL); + if (HR_FAILED(hr)) { + lpTable->Release(); + //MAPI_TRACE2( "IterateHierarchy: SeekRow failed: 0x%lx, %d\n", (long)hr, (int)hr); + return( FALSE); + } + + int cNumRows = 0; + LPSRowSet lpRow; + BOOL keepGoing = TRUE; + BOOL bResult = TRUE; + do { + + lpRow = NULL; + hr = lpTable->QueryRows( 1, 0, &lpRow); + + if(HR_FAILED(hr)) { + //MAPI_TRACE2( "QueryRows failed: 0x%lx, %d\n", (long)hr, (int)hr); + bResult = FALSE; + break; + } + + if(lpRow) { + cNumRows = lpRow->cRows; + + if (cNumRows) { + LPENTRYID lpEntry = (LPENTRYID) lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; + ULONG cb = lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; + ULONG oType = lpRow->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.ul; + + printf(" %s\n",lpRow->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA); + keepGoing = HandleHierarchyItem( oType, cb, lpEntry,aFolders); + + } + MyFreeProws( lpRow); + } + + } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing); + + lpTable->Release(); + + if (bResult && !keepGoing) + bResult = FALSE; + + return( bResult); +} +BOOL nsMapiAddressBook::HandleHierarchyItem( ULONG oType, ULONG cb, LPENTRYID pEntry,nsMapiEntryArray& aFolders) +{ + ULONG objType=0; + if (oType == MAPI_FOLDER ) + { + IABContainer * pFolder; + if (!OpenEntry( + cb, + pEntry, + 0, + NULL, + &objType, + (LPUNKNOWN *) &pFolder)) + { + LPSPropValue pVal; + + + pVal = GetMapiProperty( pFolder, PR_CONTAINER_CLASS); + if (pVal) + { + printf(" %s\n",pVal->Value.lpszA); + if (strcmp("IPF.Contact",pVal->Value.lpszA) == 0) + { + SPropValue *currentValue=GetMapiProperty( pFolder, PR_ENTRYID);; + + aFolders.AddItem(currentValue->Value.bin.cb, + NS_REINTERPRET_CAST(LPENTRYID, currentValue->Value.bin.lpb)) ; + + //IterateContents(pFolder); + } + pFolder->Release(); + } + } + } + else + { + //MAPI_TRACE1( "GetStoreFolders - HandleHierarchyItem: Unhandled ObjectType: %ld\n", oType); + } + + return( TRUE); +} + + +BOOL nsMapiAddressBook::GetFolders(nsMapiEntryArray& aFolders) +{ + aFolders.CleanUp() ; + nsMapiInterfaceWrapper rootFolder ; + nsMapiInterfaceWrapper folders ; + ULONG objType = 0 ; + ULONG rowCount = 0 ; + + LPMAPITABLE lpTable; + + mLastError = mRootSession->GetMsgStoresTable( 0, &lpTable); + if (HR_FAILED(mLastError)) { + printf("Cannot open MAPI MsgStores %08x.\n", mLastError) ; + return mLastError; + } + + mLastError = lpTable->GetRowCount( 0, &rowCount); + + mLastError = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0); + if (FAILED(mLastError)) { + lpTable->Release(); + return( mLastError); + } + mLastError = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL); + if (FAILED(mLastError)) { + lpTable->Release(); + return mLastError; + } + + int cNumRows = 0; + LPSRowSet lpRow; + BOOL keepGoing = TRUE; + BOOL bResult = TRUE; + do { + + lpRow = NULL; + mLastError = lpTable->QueryRows( 1, 0, &lpRow); + + if(HR_FAILED(mLastError)) { + bResult = FALSE; + break; + } + + if(lpRow) { + cNumRows = lpRow->cRows; + + if (cNumRows) { + LPENTRYID lpEID = (LPENTRYID) lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; + ULONG cbEID = lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; + ULONG oType = lpRow->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.ul; + + printf("%s\n",lpRow->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA); + + keepGoing = HandleContentsItem( oType, cbEID, lpEID,aFolders); + } + MyFreeProws( lpRow); + } + + } while ( SUCCEEDED(mLastError) && cNumRows && lpRow && keepGoing); + + lpTable->Release(); + + //aFolders.AddItem(currentValue.Value.bin.cb, + // NS_REINTERPRET_CAST(LPENTRYID, currentValue.Value.bin.lpb)) ; + return HR_SUCCEEDED(mLastError) ; +} +BOOL nsMapiAddressBook::GetContents(const nsMapiEntry& aParent, LPSRestriction aRestriction, + nsMapiEntryArray *aList, ULONG aMapiType) +{ + if (aList != NULL) { aList->CleanUp(); } + nsMapiInterfaceWrapper parent ; + nsMapiInterfaceWrapper contents ; + ULONG objType = 0 ; + ULONG rowCount = 0 ; + + + IMAPIProp *pFolder; + + mLastError = OpenEntry(aParent.mByteCount, aParent.mEntryId, + 0,NULL, &objType,(LPUNKNOWN *) &pFolder); + if (HR_FAILED(mLastError)) + { + PRINTF(("Cannot open folder %08x.\n", mLastError)) ; + return FALSE ; + } + + LPSPropValue msgClass=GetMapiProperty(pFolder,PR_MESSAGE_CLASS); + if (msgClass && strcmp("IPM.DistList",msgClass->Value.lpszA) == 0) + { + HRESULT hr; + LPSPropValue aValue = NULL ; + ULONG aValueCount = 0 ; + + LPSPropTagArray properties = NULL ; + mMAPIAllocateBuffer(CbNewSPropTagArray(1), + (void **)&properties) ; + properties->cValues = 1 ; + properties->aulPropTag [0] = GetEmailPropertyTag(pFolder,0x8054);//PR_CONTACT_ENTRYIDS; + hr = pFolder->GetProps(properties, 0, &aValueCount, &aValue) ; + + SBinaryArray *sa=(SBinaryArray *)&aValue->Value.bin; + + LPENTRYID lpEID; + ULONG cbEID; + + ULONG idx; + for (idx=0;idxcValues ;idx++) + { + lpEID= (LPENTRYID) sa->lpbin[idx].lpb; + cbEID = sa->lpbin[idx].cb; + aList->AddItem(cbEID,lpEID); + //GetMAPIProperties(cbEID,lpEID); + } + pFolder->Release(); + } + else + { + pFolder->Release(); + mLastError = OpenEntry(aParent.mByteCount, aParent.mEntryId, + &IID_IMAPIContainer, 0, &objType, + parent) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot open parent %08x.\n", mLastError)) ; + return FALSE ; + } + + // Here, flags for WAB and MAPI could be different, so this works + // only as long as we don't want to use any flag in GetContentsTable + mLastError = parent->GetContentsTable(0, contents) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get contents %08x.\n", mLastError)) ; + return FALSE ; + } + if (aRestriction != NULL) { + mLastError = contents->Restrict(aRestriction, 0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot set restriction %08x.\n", mLastError)) ; + return FALSE ; + } + } + mLastError = contents->SetColumns((LPSPropTagArray) &ContentsColumns, 0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot set columns %08x.\n", mLastError)) ; + return FALSE ; + } + mLastError = contents->GetRowCount(0, &rowCount) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get result count %08x.\n", mLastError)) ; + return FALSE ; + } + //if (aList != NULL) { *aList = new nsMapiEntry [rowCount] ; } + //aNbElements = 0 ; + do { + LPSRowSet rowSet = NULL ; + + rowCount = 0 ; + mLastError = contents->QueryRows(1, 0, &rowSet) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot query rows %08x.\n", mLastError)) ; + return FALSE ; + } + rowCount = rowSet->cRows ; + if (rowCount > 0 && aList != NULL) + { + if (aMapiType == 0 || rowSet->aRow->lpProps[ContentsColumnObjectType].Value.ul == aMapiType) + { + SPropValue& currentValue = rowSet->aRow->lpProps[ContentsColumnEntryId] ; + aList->AddItem(currentValue.Value.bin.cb, + NS_REINTERPRET_CAST(LPENTRYID, currentValue.Value.bin.lpb)) ; + } + else if (aMapiType == MAPI_DISTLIST) + { + if (strcmp("IPM.DistList",rowSet->aRow->lpProps[ContentsColumnMessageClass].Value.lpszA)==0) + { + SPropValue& currentValue = rowSet->aRow->lpProps[ContentsColumnEntryId] ; + aList->AddItem(currentValue.Value.bin.cb, + NS_REINTERPRET_CAST(LPENTRYID, currentValue.Value.bin.lpb)) ; + + } + } + + } + MyFreeProws(rowSet) ; + } while (rowCount > 0) ; + } + + + return TRUE ; +} + +BOOL nsMapiAddressBook::GetMAPIProperties(const nsMapiEntry& aObject, const ULONG *aPropertyTags, + ULONG aNbProperties, LPSPropValue& aValue, + ULONG& aValueCount) +{ + LPMAPIPROP object ; + IMsgStore * mdb=NULL; + ULONG objType = 0 ; + LPSPropTagArray properties = NULL ; + ULONG i = 0 ; + + mLastError = OpenEntry(aObject.mByteCount, aObject.mEntryId, + &IID_IMAPIProp, 0, &objType, + (IUnknown **)&object) ; + + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot open entry %08x.\n", mLastError)) ; + return FALSE ; + } + AllocateBuffer(CbNewSPropTagArray(aNbProperties), + NS_REINTERPRET_CAST(void **, &properties)) ; + properties->cValues = aNbProperties ; + for (i = 0 ; i < aNbProperties ; ++ i) + { + + properties->aulPropTag [i] = aPropertyTags [i] ; + + if (aPropertyTags [i] == PR_EMAIL_ADDRESS_A || aPropertyTags [i] == PR_EMAIL_ADDRESS_W) + { + LPSPropValue addr=GetMapiProperty(object,PR_EMAIL_ADDRESS_W); + if (!addr || PROP_TYPE( addr->ulPropTag) == PT_ERROR || addr->Value.l == MAPI_E_NOT_FOUND) + { + addr=GetMapiProperty(object,PR_EMAIL_ADDRESS_A); + if (!addr || PROP_TYPE( addr->ulPropTag) == PT_ERROR || addr->Value.l == MAPI_E_NOT_FOUND) + { + ULONG kPriEmailColumn=GetEmailPropertyTag(object,OUTLOOK_EMAIL1_MAPI_ID1); + //aPropertyTags [i] = kPriEmailColumn; + properties->aulPropTag [i] = kPriEmailColumn; + } + } + } + + + } + mLastError = object->GetProps(properties, 0, &aValueCount, &aValue) ; + FreeBuffer(properties) ; + + object->Release(); + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get props %08x.\n", mLastError)) ; + } + return HR_SUCCEEDED(mLastError) ; +} + +BOOL nsMapiAddressBook::SetMAPIProperties(const nsMapiEntry& aObject, ULONG aNbProperties, + const LPSPropValue& aValues) +{ + nsMapiInterfaceWrapper object ; + ULONG objType = 0 ; + LPSPropProblemArray problems = NULL ; + + mLastError = OpenEntry(aObject.mByteCount, aObject.mEntryId, + &IID_IMAPIProp, MAPI_MODIFY, &objType, + object) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot open entry %08x.\n", mLastError)) ; + return FALSE ; + } + mLastError = object->SetProps(aNbProperties, aValues, &problems) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot update the object %08x.\n", mLastError)) ; + return FALSE ; + } + if (problems != NULL) { + for (ULONG i = 0 ; i < problems->cProblem ; ++ i) { + PRINTF(("Problem %d: index %d code %08x.\n", i, + problems->aProblem [i].ulIndex, + problems->aProblem [i].scode)) ; + } + } + mLastError = object->SaveChanges(0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot commit changes %08x.\n", mLastError)) ; + } + return HR_SUCCEEDED(mLastError) ; +} + +BOOL nsMapiAddressBook::GetDefaultContainer(nsMapiEntry& aContainer) +{ + LPENTRYID entryId = NULL ; + ULONG byteCount = 0 ; + + //mLastError = mAddressBook->GetPAB(&byteCount, &entryId) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get PAB %08x.\n", mLastError)) ; + return FALSE ; + } + aContainer.Assign(byteCount, entryId) ; + FreeBuffer(entryId) ; + return TRUE ; +} + +BOOL nsMapiAddressBook::IsOK(void) +{ + return mRootSession != NULL ; +} + BOOL nsMapiAddressBook::Initialize(void) { - if (mAddressBook) { return TRUE ; } + if (IsOK()) { return TRUE ; } nsAutoLock guard(mMutex) ; if (!LoadMapiLibrary()) { PRINTF(("Cannot load library.\n")) ; return FALSE ; } - mAddressBook = mRootBook ; return TRUE ; } @@ -182,7 +761,65 @@ mMAPIFreeBuffer(aBuffer) ; } +ULONG nsMapiAddressBook::GetEmailPropertyTag(LPMAPIPROP lpProp, LONG nameID) +{ + static GUID emailGUID = + { + 0x00062004, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 + }; + + + MAPINAMEID mapiNameID; + mapiNameID.lpguid = &emailGUID; + mapiNameID.ulKind = MNID_ID; + mapiNameID.Kind.lID = nameID; + LPMAPINAMEID lpMapiNames = &mapiNameID; + LPSPropTagArray lpMailTagArray = NULL; + HRESULT result = lpProp->GetIDsFromNames(1L, &lpMapiNames, 0, &lpMailTagArray); + if (result == S_OK) + { + ULONG lTag = lpMailTagArray->aulPropTag[0]; + mMAPIFreeBuffer(lpMailTagArray); + return lTag; + } + else + return 0L; +} +BOOL nsMapiAddressBook::GetPropertyLong(const nsMapiEntry& aObject, + ULONG aPropertyTag, + ULONG& aValue) +{ + aValue = 0 ; + LPSPropValue values = NULL ; + ULONG valueCount = 0 ; + if (PR_OBJECT_TYPE == aPropertyTag) + { + IMAPIProp *pFolder; + ULONG objType=0; + mLastError = OpenEntry(aObject.mByteCount, aObject.mEntryId, + 0,NULL, &objType,(LPUNKNOWN *) &pFolder); + if (HR_FAILED(mLastError)) + { + PRINTF(("Cannot open folder %08x.\n", mLastError)) ; + return FALSE ; + } + LPSPropValue msgClass=GetMapiProperty(pFolder,PR_MESSAGE_CLASS); + if (msgClass && strcmp("IPM.DistList",msgClass->Value.lpszA) == 0) + { + FreeBuffer(msgClass); + pFolder->Release(); + aValue = MAPI_DISTLIST; + return TRUE; + } + } + if (!GetMAPIProperties(aObject, &aPropertyTag, 1, values, valueCount)) { return FALSE ; } + if (valueCount == 1 && values != NULL && PROP_TYPE(values->ulPropTag) == PT_LONG) { + aValue = values->Value.ul ; + } + FreeBuffer(values) ; + return TRUE ; +} Index: addrbook/src/nsMapiAddressBook.h =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsMapiAddressBook.h,v retrieving revision 1.3 diff -u -w -b -i -r1.3 nsMapiAddressBook.h --- addrbook/src/nsMapiAddressBook.h 28 Sep 2001 20:06:25 -0000 1.3 +++ addrbook/src/nsMapiAddressBook.h 18 Sep 2003 09:03:15 -0000 @@ -46,6 +46,17 @@ nsMapiAddressBook(void) ; virtual ~nsMapiAddressBook(void) ; + // Get the top address books + virtual BOOL GetFolders(nsMapiEntryArray& aFolders); + + // Get a default address book container + virtual BOOL GetDefaultContainer(nsMapiEntry& aContainer); + // Is the helper correctly initialised? + virtual BOOL IsOK(void); + virtual BOOL GetPropertyLong(const nsMapiEntry& aObject, + ULONG aPropertyTag, + ULONG& aValue); + protected : // Class members to handle the library/entry points static HMODULE mLibrary ; @@ -67,10 +78,42 @@ static BOOL mInitialized ; static BOOL mLogonDone ; static LPMAPISESSION mRootSession ; - static LPADRBOOK mRootBook ; + static LPMAPISESSION mRootBook ; + // Load the MAPI environment BOOL Initialize(void) ; + + virtual HRESULT OpenEntry(ULONG cbEntryID, + LPENTRYID lpEntryID, + LPCIID lpInterface, + ULONG ulFlags, + ULONG FAR * lpulObjType, + LPUNKNOWN FAR * lppUnk + ) + { + return mRootBook->OpenEntry(cbEntryID, + lpEntryID, + lpInterface, + ulFlags, + lpulObjType, + lppUnk + ); + } + + + // Retrieve the contents of a container, with an optional restriction + virtual BOOL GetContents(const nsMapiEntry& aParent, LPSRestriction aRestriction, + nsMapiEntryArray *aList, ULONG aMapiType) ; + // Retrieve the values of a set of properties on a MAPI object + virtual BOOL GetMAPIProperties(const nsMapiEntry& aObject, const ULONG *aPropertyTags, + ULONG aNbProperties, + LPSPropValue& aValues, ULONG& aValueCount) ; + // Set the values of a set of properties on a MAPI object + virtual BOOL SetMAPIProperties(const nsMapiEntry& aObject, ULONG aNbProperties, + const LPSPropValue& aValues) ; + + // Allocation of a buffer for transmission to interfaces virtual void AllocateBuffer(ULONG aByteCount, LPVOID *aBuffer) ; // Destruction of a buffer provided by the interfaces @@ -78,6 +121,13 @@ // Library management static BOOL LoadMapiLibrary(void) ; static void FreeMapiLibrary(void) ; + + BOOL HandleContentsItem(ULONG oType, ULONG cb, LPENTRYID pEntry,nsMapiEntryArray& aFolders); + LPSPropValue GetMapiProperty( LPMAPIPROP pProp, ULONG tag); + BOOL GetEntryIdFromProp( LPSPropValue pVal, ULONG& cbEntryId, LPENTRYID& lpEntryId, BOOL delVal=FALSE); + BOOL HandleHierarchyItem( ULONG oType, ULONG cb, LPENTRYID pEntry,nsMapiEntryArray& aFolders); + BOOL IterateHierarchy(IMAPIContainer * pFolder, nsMapiEntryArray& aFolders,ULONG flags=0); + ULONG GetEmailPropertyTag(LPMAPIPROP lpProp, LONG nameID); private : } ; Index: addrbook/src/nsWabAddressBook.cpp =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsWabAddressBook.cpp,v retrieving revision 1.6 diff -u -w -b -i -r1.6 nsWabAddressBook.cpp --- addrbook/src/nsWabAddressBook.cpp 30 Oct 2001 07:59:16 -0000 1.6 +++ addrbook/src/nsWabAddressBook.cpp 18 Sep 2003 09:03:15 -0000 @@ -47,6 +47,22 @@ #define PRINTF(args) PR_LOG(gWabAddressBookLog, PR_LOG_DEBUG, args) +enum +{ + ContentsColumnEntryId = 0, + ContentsColumnObjectType, + ContentsColumnsSize +} ; + +static const SizedSPropTagArray(ContentsColumnsSize, ContentsColumns) = +{ + ContentsColumnsSize, + { + PR_ENTRYID, + PR_OBJECT_TYPE + } +} ; + HMODULE nsWabAddressBook::mLibrary = NULL ; PRInt32 nsWabAddressBook::mLibUsage = 0 ; LPWABOPEN nsWabAddressBook::mWABOpen = NULL ; @@ -95,7 +111,7 @@ MOZ_DECL_CTOR_COUNTER(nsWabAddressBook) nsWabAddressBook::nsWabAddressBook(void) -: nsAbWinHelper() +: nsAbWinHelper(),mAddressBook(NULL) { BOOL result = Initialize() ; @@ -108,6 +124,221 @@ nsAutoLock guard(mMutex) ; FreeWabLibrary() ; MOZ_COUNT_DTOR(nsWabAddressBook) ; +} + +BOOL nsWabAddressBook::GetFolders(nsMapiEntryArray& aFolders) +{ + aFolders.CleanUp() ; + nsMapiInterfaceWrapper rootFolder ; + nsMapiInterfaceWrapper folders ; + ULONG objType = 0 ; + ULONG rowCount = 0 ; + SRestriction restriction ; + SPropTagArray folderColumns ; + + mLastError = OpenEntry(0, NULL, NULL, 0, &objType, + rootFolder) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot open root %08x.\n", mLastError)) ; + return FALSE ; + } + mLastError = rootFolder->GetHierarchyTable(0, folders) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get hierarchy %08x.\n", mLastError)) ; + return FALSE ; + } + // We only take into account modifiable containers, + // otherwise, we end up with all the directory services... + restriction.rt = RES_BITMASK ; + restriction.res.resBitMask.ulPropTag = PR_CONTAINER_FLAGS ; + restriction.res.resBitMask.relBMR = BMR_NEZ ; + restriction.res.resBitMask.ulMask = AB_MODIFIABLE ; + mLastError = folders->Restrict(&restriction, 0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot restrict table %08x.\n", mLastError)) ; + } + folderColumns.cValues = 1 ; + folderColumns.aulPropTag [0] = PR_ENTRYID ; + mLastError = folders->SetColumns(&folderColumns, 0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot set columns %08x.\n", mLastError)) ; + return FALSE ; + } + mLastError = folders->GetRowCount(0, &rowCount) ; + if (HR_SUCCEEDED(mLastError)) { + do { + LPSRowSet rowSet = NULL ; + + rowCount = 0 ; + mLastError = folders->QueryRows(1, 0, &rowSet) ; + if (HR_SUCCEEDED(mLastError)) { + rowCount = rowSet->cRows ; + if (rowCount > 0) { + SPropValue& currentValue = rowSet->aRow->lpProps [0] ; + + aFolders.AddItem(currentValue.Value.bin.cb, + NS_REINTERPRET_CAST(LPENTRYID, currentValue.Value.bin.lpb)) ; + } + MyFreeProws(rowSet) ; + } + else { + PRINTF(("Cannot query rows %08x.\n", mLastError)) ; + } + } while (rowCount > 0) ; + } + return HR_SUCCEEDED(mLastError) ; +} +BOOL nsWabAddressBook::GetContents(const nsMapiEntry& aParent, LPSRestriction aRestriction, + nsMapiEntryArray *aList, ULONG aMapiType) +{ + if (aList != NULL) { aList->CleanUp(); } + nsMapiInterfaceWrapper parent ; + nsMapiInterfaceWrapper contents ; + ULONG objType = 0 ; + ULONG rowCount = 0 ; + + mLastError = OpenEntry(aParent.mByteCount, aParent.mEntryId, + &IID_IMAPIContainer, 0, &objType, + parent) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot open parent %08x.\n", mLastError)) ; + return FALSE ; + } + // Here, flags for WAB and MAPI could be different, so this works + // only as long as we don't want to use any flag in GetContentsTable + mLastError = parent->GetContentsTable(0, contents) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get contents %08x.\n", mLastError)) ; + return FALSE ; + } + if (aRestriction != NULL) { + mLastError = contents->Restrict(aRestriction, 0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot set restriction %08x.\n", mLastError)) ; + return FALSE ; + } + } + mLastError = contents->SetColumns((LPSPropTagArray) &ContentsColumns, 0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot set columns %08x.\n", mLastError)) ; + return FALSE ; + } + mLastError = contents->GetRowCount(0, &rowCount) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get result count %08x.\n", mLastError)) ; + return FALSE ; + } + //if (aList != NULL) { *aList = new nsMapiEntry [rowCount] ; } + //aNbElements = 0 ; + do { + LPSRowSet rowSet = NULL ; + + rowCount = 0 ; + mLastError = contents->QueryRows(1, 0, &rowSet) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot query rows %08x.\n", mLastError)) ; + return FALSE ; + } + rowCount = rowSet->cRows ; + if (rowCount > 0 && + (aMapiType == 0 || + rowSet->aRow->lpProps[ContentsColumnObjectType].Value.ul == aMapiType)) { + if (aList != NULL) { + SPropValue& currentValue = rowSet->aRow->lpProps[ContentsColumnEntryId] ; + + aList->AddItem(currentValue.Value.bin.cb, + NS_REINTERPRET_CAST(LPENTRYID, currentValue.Value.bin.lpb)) ; + + } + } + MyFreeProws(rowSet) ; + } while (rowCount > 0) ; + return TRUE ; +} + +BOOL nsWabAddressBook::GetMAPIProperties(const nsMapiEntry& aObject, const ULONG *aPropertyTags, + ULONG aNbProperties, LPSPropValue& aValue, + ULONG& aValueCount) +{ + nsMapiInterfaceWrapper object ; + IMsgStore * mdb=NULL; + ULONG objType = 0 ; + LPSPropTagArray properties = NULL ; + ULONG i = 0 ; + + mLastError = OpenEntry(aObject.mByteCount, aObject.mEntryId, + &IID_IMAPIProp, 0, &objType, + object) ; + + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot open entry %08x.\n", mLastError)) ; + return FALSE ; + } + AllocateBuffer(CbNewSPropTagArray(aNbProperties), + NS_REINTERPRET_CAST(void **, &properties)) ; + properties->cValues = aNbProperties ; + for (i = 0 ; i < aNbProperties ; ++ i) { + properties->aulPropTag [i] = aPropertyTags [i] ; + } + mLastError = object->GetProps(properties, 0, &aValueCount, &aValue) ; + FreeBuffer(properties) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get props %08x.\n", mLastError)) ; + } + return HR_SUCCEEDED(mLastError) ; +} + +BOOL nsWabAddressBook::SetMAPIProperties(const nsMapiEntry& aObject, ULONG aNbProperties, + const LPSPropValue& aValues) +{ + nsMapiInterfaceWrapper object ; + ULONG objType = 0 ; + LPSPropProblemArray problems = NULL ; + + mLastError = OpenEntry(aObject.mByteCount, aObject.mEntryId, + &IID_IMAPIProp, MAPI_MODIFY, &objType, + object) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot open entry %08x.\n", mLastError)) ; + return FALSE ; + } + mLastError = object->SetProps(aNbProperties, aValues, &problems) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot update the object %08x.\n", mLastError)) ; + return FALSE ; + } + if (problems != NULL) { + for (ULONG i = 0 ; i < problems->cProblem ; ++ i) { + PRINTF(("Problem %d: index %d code %08x.\n", i, + problems->aProblem [i].ulIndex, + problems->aProblem [i].scode)) ; + } + } + mLastError = object->SaveChanges(0) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot commit changes %08x.\n", mLastError)) ; + } + return HR_SUCCEEDED(mLastError) ; +} + +BOOL nsWabAddressBook::GetDefaultContainer(nsMapiEntry& aContainer) +{ + LPENTRYID entryId = NULL ; + ULONG byteCount = 0 ; + + mLastError = mAddressBook->GetPAB(&byteCount, &entryId) ; + if (HR_FAILED(mLastError)) { + PRINTF(("Cannot get PAB %08x.\n", mLastError)) ; + return FALSE ; + } + aContainer.Assign(byteCount, entryId) ; + FreeBuffer(entryId) ; + return TRUE ; +} + +BOOL nsWabAddressBook::IsOK(void) +{ + return mAddressBook != NULL ; } BOOL nsWabAddressBook::Initialize(void) Index: addrbook/src/nsWabAddressBook.h =================================================================== RCS file: /cvsroot/mozilla/mailnews/addrbook/src/nsWabAddressBook.h,v retrieving revision 1.2 diff -u -w -b -i -r1.2 nsWabAddressBook.h --- addrbook/src/nsWabAddressBook.h 28 Sep 2001 20:06:25 -0000 1.2 +++ addrbook/src/nsWabAddressBook.h 18 Sep 2003 09:03:15 -0000 @@ -47,6 +47,13 @@ nsWabAddressBook(void) ; virtual ~nsWabAddressBook(void) ; + // Get the top address books + virtual BOOL GetFolders(nsMapiEntryArray& aFolders); + + // Get a default address book container + virtual BOOL GetDefaultContainer(nsMapiEntry& aContainer); + // Is the helper correctly initialised? + virtual BOOL IsOK(void); protected : // Session and address book that will be shared by all instances // (see nsMapiAddressBook.h for details) @@ -57,8 +64,40 @@ static HMODULE mLibrary ; static LPWABOPEN mWABOpen ; + LPADRBOOK mAddressBook ; + // Load the WAB environment BOOL Initialize(void) ; + + virtual HRESULT OpenEntry(ULONG cbEntryID, + LPENTRYID lpEntryID, + LPCIID lpInterface, + ULONG ulFlags, + ULONG FAR * lpulObjType, + LPUNKNOWN FAR * lppUnk + ) + { + return mAddressBook->OpenEntry(cbEntryID, + lpEntryID, + lpInterface, + ulFlags, + lpulObjType, + lppUnk + ); + } + + + // Retrieve the contents of a container, with an optional restriction + virtual BOOL GetContents(const nsMapiEntry& aParent, LPSRestriction aRestriction, + nsMapiEntryArray *aList, ULONG aMapiType) ; + // Retrieve the values of a set of properties on a MAPI object + virtual BOOL GetMAPIProperties(const nsMapiEntry& aObject, const ULONG *aPropertyTags, + ULONG aNbProperties, + LPSPropValue& aValues, ULONG& aValueCount) ; + // Set the values of a set of properties on a MAPI object + virtual BOOL SetMAPIProperties(const nsMapiEntry& aObject, ULONG aNbProperties, + const LPSPropValue& aValues) ; + // Allocation of a buffer for transmission to interfaces virtual void AllocateBuffer(ULONG aByteCount, LPVOID *aBuffer) ; // Destruction of a buffer provided by the interfaces