LPMAPITABLE CExMapi::GetHierarchy(LPMAPIFOLDER pFolder) { if(!pFolder) { pFolder=m_pFolder; if(!pFolder) return NULL; } RELEASE(m_pHierarchy); if(pFolder->GetHierarchyTable(0,&m_pHierarchy)!=S_OK) return NULL; const int nProperties=2; SizedSPropTagArray(nProperties,Columns)={nProperties,{PR_DISPLAY_NAME, PR_ENTRYID}}; if(m_pHierarchy->SetColumns((LPSPropTagArray)&Columns, 0)==S_OK) return m_pHierarchy; return NULL; }
HRESULT DetectFolderDetails(LPMAPIFOLDER lpFolder, string *lpName, string *lpClass, ULONG *lpFolderType) { HRESULT hr = hrSuccess; LPSPropValue lpPropertyArray = NULL; ULONG ulPropertyCount = 0; SizedSPropTagArray(3, PropertyTagArray) = { 3, { PR_DISPLAY_NAME_A, PR_CONTAINER_CLASS_A, PR_FOLDER_TYPE, } }; hr = lpFolder->GetProps((LPSPropTagArray)&PropertyTagArray, 0, &ulPropertyCount, &lpPropertyArray); if (FAILED(hr)) { cout << "Failed to obtain all properties." << endl; goto exit; } *lpFolderType = 0; for (ULONG i = 0; i < ulPropertyCount; i++) { if (PROP_TYPE(lpPropertyArray[i].ulPropTag) == PT_ERROR) hr = MAPI_E_INVALID_OBJECT; else if (lpPropertyArray[i].ulPropTag == PR_DISPLAY_NAME_A) *lpName = lpPropertyArray[i].Value.lpszA; else if (lpPropertyArray[i].ulPropTag == PR_CONTAINER_CLASS_A) *lpClass = lpPropertyArray[i].Value.lpszA; else if (lpPropertyArray[i].ulPropTag == PR_FOLDER_TYPE) *lpFolderType = lpPropertyArray[i].Value.ul; } /* * As long as we found what we were looking for, we should be satisfied. */ if (!lpName->empty() && !lpClass->empty()) hr = hrSuccess; exit: if (lpPropertyArray) MAPIFreeBuffer(lpPropertyArray); return hr; }
CString CExMapi::GetFolderName(LPMAPIFOLDER lpFolder) { CString folderName = L""; if(!lpFolder) return folderName; LPSPropValue props=NULL; ULONG cValues=0; ULONG rgTags[]={ 1, PR_DISPLAY_NAME }; if(SUCCEEDED(lpFolder->GetProps((LPSPropTagArray) rgTags, CExMapi::cm_nMAPICode, &cValues, &props))) { folderName = CExMapi::GetValidString(*props); } return folderName; }
BOOL CExMapi::IsContactFolder(LPMAPIFOLDER lpFolder) { if(!lpFolder) return FALSE; LPSPropValue props=NULL; ULONG cValues=0; ULONG rgTags[]={ 1, PR_CONTAINER_CLASS }; if(SUCCEEDED(lpFolder->GetProps((LPSPropTagArray) rgTags, CExMapi::cm_nMAPICode, &cValues, &props))) { CString containerClass = CExMapi::GetValidString(*props); if(containerClass == L"IPF.Contact") return TRUE; } return FALSE; }
LPMAPIFOLDER CMAPIEx::GetNextSubFolder(CString& strFolderName, LPMAPIFOLDER pFolder) { if (!m_pHierarchy) return NULL; if (!pFolder) { pFolder = m_pFolder; if (!pFolder) return FALSE; } DWORD dwObjType; LPSRowSet pRows = NULL; LPMAPIFOLDER pSubFolder = NULL; if (m_pHierarchy->QueryRows(1, 0, &pRows) == S_OK) { if (pRows->cRows) { if (pFolder->OpenEntry(pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.cb, (LPENTRYID)pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.lpb, NULL, MAPI_MODIFY, &dwObjType, (LPUNKNOWN *)&pSubFolder) == S_OK) { strFolderName = GetValidString(pRows->aRow[0].lpProps[0]); } } FreeProws(pRows); } MAPIFreeBuffer(pRows); return pSubFolder; }
void CMapiApi::GetStoreInfo( CMapiFolder *pFolder, long *pSzContents) { HRESULT hr; LPMDB lpMdb; if (pSzContents) *pSzContents = 0; if (!OpenStore( pFolder->GetCBEntryID(), pFolder->GetEntryID(), &lpMdb)) return; LPSPropValue pVal; /* pVal = GetMapiProperty( lpMdb, PR_DISPLAY_NAME); ReportStringProp( " Message store name:", pVal); pVal = GetMapiProperty( lpMdb, PR_MDB_PROVIDER); ReportUIDProp( " Message store provider:", pVal); pVal = GetMapiProperty( lpMdb, PR_COMMENT); ReportStringProp( " Message comment:", pVal); pVal = GetMapiProperty( lpMdb, PR_ACCESS_LEVEL); ReportLongProp( " Message store Access Level:", pVal); pVal = GetMapiProperty( lpMdb, PR_STORE_SUPPORT_MASK); ReportLongProp( " Message store support mask:", pVal); pVal = GetMapiProperty( lpMdb, PR_STORE_STATE); ReportLongProp( " Message store state:", pVal); pVal = GetMapiProperty( lpMdb, PR_OBJECT_TYPE); ReportLongProp( " Message store object type:", pVal); pVal = GetMapiProperty( lpMdb, PR_VALID_FOLDER_MASK); ReportLongProp( " Message store valid folder mask:", pVal); pVal = GetMapiProperty( lpMdb, 0x8001001e); ReportStringProp( " Message prop 0x8001001e:", pVal); // This key appears to be the OMI Account Manager account that corresponds // to this message store. This is important for IMAP accounts // since we may not want to import messages from an IMAP store! // Seems silly if you ask me! // In order to test this, we'll need the registry key to look under to determine // if it contains the "IMAP Server" value, if it does then we are an // IMAP store, if not, then we are a non-IMAP store - which may always mean // a regular store that should be imported. pVal = GetMapiProperty( lpMdb, 0x80000003); ReportLongProp( " Message prop 0x80000003:", pVal); // ListProperties( lpMdb); */ pVal = GetMapiProperty( lpMdb, PR_IPM_SUBTREE_ENTRYID); if (pVal) { ULONG cbEntry; LPENTRYID pEntry; LPMAPIFOLDER lpSubTree = NULL; if (GetEntryIdFromProp( pVal, cbEntry, pEntry)) { // Open up the folder! ULONG ulObjType; hr = lpMdb->OpenEntry( cbEntry, pEntry, NULL, 0, &ulObjType, (LPUNKNOWN *) &lpSubTree); MAPIFreeBuffer( pEntry); if (SUCCEEDED( hr) && lpSubTree) { // Find out if there are any contents in the // tree. LPMAPITABLE lpTable; hr = lpSubTree->GetHierarchyTable( 0, &lpTable); if (HR_FAILED(hr)) { MAPI_TRACE2( "GetStoreInfo: GetHierarchyTable failed: 0x%lx, %d\n", (long)hr, (int)hr); } else { ULONG rowCount; hr = lpTable->GetRowCount( 0, &rowCount); lpTable->Release(); if (SUCCEEDED( hr) && pSzContents) *pSzContents = (long) rowCount; } lpSubTree->Release(); } } } }
BOOL CMapiApi::IterateHierarchy( CMapiHierarchyIter *pIter, LPMAPIFOLDER pFolder, 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( flags, &lpTable); if (HR_FAILED(hr)) { m_lastError = 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)) { m_lastError = 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)) { m_lastError = 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); m_lastError = 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; if (pIter) keepGoing = pIter->HandleHierarchyItem( oType, cb, lpEntry); else keepGoing = HandleHierarchyItem( oType, cb, lpEntry); } FreeProws( lpRow); } } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing); lpTable->Release(); if (bResult && !keepGoing) bResult = FALSE; return( bResult); }
BOOL CMapiApi::IterateContents( CMapiContentIter *pIter, LPMAPIFOLDER pFolder, ULONG flags) { // flags can be 0 or MAPI_ASSOCIATED // MAPI_ASSOCIATED is usually used for forms and views HRESULT hr; LPMAPITABLE lpTable; hr = pFolder->GetContentsTable( flags, &lpTable); if (FAILED(hr)) { MAPI_TRACE2( "GetContentsTable failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } ULONG rowCount; hr = lpTable->GetRowCount( 0, &rowCount); if (!rowCount) { MAPI_TRACE0( " Empty Table\n"); } hr = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0); if (FAILED(hr)) { lpTable->Release(); MAPI_TRACE2( "SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL); if (FAILED(hr)) { lpTable->Release(); MAPI_TRACE2( "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 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; keepGoing = HandleContentsItem( oType, cbEID, lpEID); MAPI_TRACE1( " ObjectType: %ld\n", oType); } FreeProws( lpRow); } } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing); lpTable->Release(); return( bResult); }
HRESULT RunStoreValidation(char* strHost, char* strUser, char* strPass, char *strAltUser, bool bPublic, CHECKMAP checkmap) { HRESULT hr = hrSuccess; LPMAPISESSION lpSession = NULL; LPMDB lpStore = NULL; LPMDB lpAltStore = NULL; LPMDB lpReadStore = NULL; LPMAPIFOLDER lpRootFolder = NULL; LPMAPITABLE lpHierarchyTable = NULL; LPSRowSet lpRows = NULL; ULONG ulObjectType; ULONG ulCount; LPEXCHANGEMANAGESTORE lpIEMS = NULL; // user ULONG cbUserStoreEntryID = 0; LPENTRYID lpUserStoreEntryID = NULL; wstring strwUsername; wstring strwAltUsername; wstring strwPassword; std::set<std::string> setFolderIgnore; LPSPropValue lpAddRenProp = NULL; ULONG cbEntryIDSrc = 0; LPENTRYID lpEntryIDSrc = NULL; ECLogger *const lpLogger = new ECLogger_File(EC_LOGLEVEL_FATAL, 0, "-"); hr = MAPIInitialize(NULL); if (hr != hrSuccess) { cout << "Unable to initialize session" << endl; goto exit; } // input from commandline is current locale if (strUser) strwUsername = convert_to<wstring>(strUser); if (strPass) strwPassword = convert_to<wstring>(strPass); if (strAltUser) strwAltUsername = convert_to<wstring>(strAltUser); hr = HrOpenECSession(lpLogger, &lpSession, "zarafa-fsck", PROJECT_SVN_REV_STR, strwUsername.c_str(), strwPassword.c_str(), (const char *)strHost, 0, NULL, NULL); lpLogger->Release(); if(hr != hrSuccess) { cout << "Wrong username or password." << endl; goto exit; } if (bPublic) { hr = HrOpenECPublicStore(lpSession, &lpStore); if (hr != hrSuccess) { cout << "Failed to open public store." << endl; goto exit; } } else { hr = HrOpenDefaultStore(lpSession, &lpStore); if (hr != hrSuccess) { cout << "Failed to open default store." << endl; goto exit; } } if (!strwAltUsername.empty()) { hr = lpStore->QueryInterface(IID_IExchangeManageStore, (void **)&lpIEMS); if (hr != hrSuccess) { cout << "Cannot open ExchangeManageStore object" << endl; goto exit; } hr = lpIEMS->CreateStoreEntryID(L"", (LPTSTR)strwAltUsername.c_str(), MAPI_UNICODE | OPENSTORE_HOME_LOGON, &cbUserStoreEntryID, &lpUserStoreEntryID); if (hr != hrSuccess) { cout << "Cannot get user store id for user" << endl; goto exit; } hr = lpSession->OpenMsgStore(0, cbUserStoreEntryID, lpUserStoreEntryID, NULL, MDB_WRITE | MDB_NO_DIALOG | MDB_NO_MAIL | MDB_TEMPORARY, &lpAltStore); if (hr != hrSuccess) { cout << "Cannot open user store of user" << endl; goto exit; } lpReadStore = lpAltStore; } else { lpReadStore = lpStore; } hr = lpReadStore->OpenEntry(0, NULL, &IID_IMAPIFolder, 0, &ulObjectType, (IUnknown **)&lpRootFolder); if(hr != hrSuccess) { cout << "Failed to open root folder." << endl; goto exit; } if (HrGetOneProp(lpRootFolder, PR_IPM_OL2007_ENTRYIDS /*PR_ADDITIONAL_REN_ENTRYIDS_EX*/, &lpAddRenProp) == hrSuccess && Util::ExtractSuggestedContactsEntryID(lpAddRenProp, &cbEntryIDSrc, &lpEntryIDSrc) == hrSuccess) { setFolderIgnore.insert(string((const char*)lpEntryIDSrc, cbEntryIDSrc)); } hr = lpRootFolder->GetHierarchyTable(CONVENIENT_DEPTH, &lpHierarchyTable); if (hr != hrSuccess) { cout << "Failed to open hierarchy." << endl; goto exit; } /* * Check if we have found at least *something*. */ hr = lpHierarchyTable->GetRowCount(0, &ulCount); if(hr != hrSuccess) { cout << "Failed to count number of rows." << endl; goto exit; } else if (!ulCount) { cout << "No entries inside Calendar." << endl; goto exit; } /* * Loop through each row/entry and validate. */ while (true) { hr = lpHierarchyTable->QueryRows(20, 0, &lpRows); if (hr != hrSuccess) break; if (lpRows->cRows == 0) break; for (ULONG i = 0; i < lpRows->cRows; i++) RunFolderValidation(setFolderIgnore, lpRootFolder, &lpRows->aRow[i], checkmap); if (lpRows) { FreeProws(lpRows); lpRows = NULL; } } exit: if (lpUserStoreEntryID) MAPIFreeBuffer(lpUserStoreEntryID); if (lpIEMS) lpIEMS->Release(); if (lpRows) { FreeProws(lpRows); lpRows = NULL; } if (lpEntryIDSrc) MAPIFreeBuffer(lpEntryIDSrc); if (lpAddRenProp) MAPIFreeBuffer(lpAddRenProp); if(lpHierarchyTable) lpHierarchyTable->Release(); if (lpRootFolder) lpRootFolder->Release(); if (lpAltStore) lpAltStore->Release(); if (lpStore) lpStore->Release(); if (lpSession) lpSession->Release(); MAPIUninitialize(); return hr; }
HRESULT RunFolderValidation(const std::set<std::string> &setFolderIgnore, LPMAPIFOLDER lpRootFolder, LPSRow lpRow, CHECKMAP checkmap) { HRESULT hr = hrSuccess; LPSPropValue lpItemProperty = NULL; LPMAPIFOLDER lpFolder = NULL; ZarafaFsck *lpFsck = NULL; ULONG ulObjectType = 0; string strName; string strClass; ULONG ulFolderType = 0; lpItemProperty = PpropFindProp(lpRow->lpProps, lpRow->cValues, PR_ENTRYID); if (!lpItemProperty) { cout << "Row does not contain an EntryID." << endl; goto exit; } hr = lpRootFolder->OpenEntry(lpItemProperty->Value.bin.cb, (LPENTRYID)lpItemProperty->Value.bin.lpb, &IID_IMAPIFolder, 0, &ulObjectType, (IUnknown**)&lpFolder); if (hr != hrSuccess) { cout << "Failed to open EntryID." << endl; goto exit; } /* * Detect folder name and class. */ hr = DetectFolderDetails(lpFolder, &strName, &strClass, &ulFolderType); if (hr != hrSuccess) { if (!strName.empty()) { cout << "Unknown class, skipping entry"; cout << " \"" << strName << "\"" << endl; } else cout << "Failed to detect folder details." << endl; goto exit; } if (setFolderIgnore.find(string((const char*)lpItemProperty->Value.bin.lpb, lpItemProperty->Value.bin.cb)) != setFolderIgnore.end()) { cout << "Ignoring folder: "; cout << "\"" << strName << "\" (" << strClass << ")" << endl; goto exit; } if (ulFolderType != FOLDER_GENERIC) { cout << "Ignoring search folder: "; cout << "\"" << strName << "\" (" << strClass << ")" << endl; goto exit; } for (CHECKMAP_I i = checkmap.begin(); i != checkmap.end(); ++i) { if (i->first == strClass) { lpFsck = i->second; break; } } if (lpFsck) lpFsck->ValidateFolder(lpFolder, strName); else { cout << "Ignoring folder: "; cout << "\"" << strName << "\" (" << strClass << ")" << endl; } exit: if(lpFolder) lpFolder->Release(); return hr; }
/** * Add new folders to the favorites folder * * @param lpSession Pointer to the current mapi session * @param lpFolder Pointer to a folder in the public store, except a folder from the favorites folder * @param lpAliasName Pointer to a string containing another name for the folder * @param ulFlags Bitmask of flags that controls how the folder is added. The following flags can be set: * FAVO_FOLDER_LEVEL_BASE * Add only the folder itself * FAVO_FOLDER_LEVEL_ONE * Add the folder and the immediate subfolders only * FAVO_FOLDER_LEVEL_SUB * Add the folder and all subfolders * MAPI_UNICODE * lpAliasName parameter is in wide or multibyte format */ HRESULT AddFavoriteFolder(LPMAPIFOLDER lpShortcutFolder, LPMAPIFOLDER lpFolder, LPCTSTR lpAliasName, ULONG ulFlags) { HRESULT hr = hrSuccess; LPMAPITABLE lpTable = NULL; LPSPropValue lpsPropArray = NULL; LPSPropValue lpPropDepth = NULL; // No free needed SRowSet *lpRows = NULL; ULONG ulFolderFlags = 0; ULONG cValues = 0; SizedSPropTagArray(5, sPropsFolderInfo) = {5, { PR_DEPTH, PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY, PR_DISPLAY_NAME, PR_CONTAINER_CLASS}}; // FIXME: check vaiables // Add folders to the shorcut folder hr = lpFolder->GetProps((LPSPropTagArray)&sPropsFolderInfo, 0, &cValues, &lpsPropArray); if (FAILED(hr) != hrSuccess) //Gives always a warning goto exit; hr = AddToFavorite(lpShortcutFolder, 1, lpAliasName, ulFlags, cValues, lpsPropArray); if (hr != hrSuccess) goto exit; if (lpsPropArray) { MAPIFreeBuffer(lpsPropArray); lpsPropArray = NULL; } if (ulFlags == FAVO_FOLDER_LEVEL_SUB) { ulFolderFlags = CONVENIENT_DEPTH; } else if(ulFlags == FAVO_FOLDER_LEVEL_ONE) { ulFolderFlags = 0; }else { hr = hrSuccess; // Done goto exit; } // Get subfolders hr = lpFolder->GetHierarchyTable(ulFolderFlags, &lpTable); if (hr != hrSuccess) goto exit; hr = lpTable->SetColumns((LPSPropTagArray)&sPropsFolderInfo, 0); if (hr != hrSuccess) goto exit; // Add the favorite recusive depended what the flags are while(true) { hr = lpTable->QueryRows (1, 0, &lpRows); if (hr != hrSuccess) goto exit; if (lpRows->cRows == 0) break; lpPropDepth = PpropFindProp(lpRows->aRow[0].lpProps,lpRows->aRow[0].cValues, PR_DEPTH); if (lpPropDepth == NULL) { hr = MAPI_E_CORRUPT_DATA;// Break the action goto exit; } hr = AddToFavorite(lpShortcutFolder, lpPropDepth->Value.ul + 1, NULL, 0, lpRows->aRow[0].cValues, lpRows->aRow[0].lpProps); if (hr != hrSuccess) { // Break the action goto exit; } FreeProws(lpRows); lpRows = NULL; } //while(true) exit: if (lpTable) lpTable->Release(); if (lpRows) FreeProws(lpRows); if (lpsPropArray) MAPIFreeBuffer(lpsPropArray); return hr; }
ULONGLONG ComputeFolderSize( _In_z_ LPWSTR lpszProfile, _In_ LPMAPIFOLDER lpFolder, _In_ ULONG ulFolder, _In_z_ LPWSTR lpszFolder) { DebugPrint(DBGGeneric,"ComputeFolderSize: Calculating size (including subfolders) for folder %u / %ws from profile %ws \n", ulFolder, lpszFolder?lpszFolder:L"", lpszProfile); // printf("ComputeFolderSize: Calculating size (including subfolders) for folder %i / %ws from profile %ws \n", ulFolder, lpszFolder?lpszFolder:L"", lpszProfile); HRESULT hRes = S_OK; if (lpFolder) { LPMAPITABLE lpTable = NULL; LPSRowSet lpRow = NULL; ULONG i = 0; ULONGLONG ullSize = 0; enum { ePR_DISPLAY_NAME_W, ePR_ENTRYID, ePR_FOLDER_TYPE, NUM_COLS }; static const SizedSPropTagArray(NUM_COLS, rgColProps) = { NUM_COLS, PR_DISPLAY_NAME_W, PR_ENTRYID, PR_FOLDER_TYPE, }; // Size of this folder ullSize += ComputeSingleFolderSize(lpFolder); // Size of children WC_MAPI(lpFolder->GetHierarchyTable(MAPI_DEFERRED_ERRORS, &lpTable)); if (SUCCEEDED(hRes) && lpTable) { WC_MAPI(lpTable->SetColumns((LPSPropTagArray)&rgColProps, TBL_ASYNC)); if (!FAILED(hRes)) for (;;) { hRes = S_OK; if (lpRow) FreeProws(lpRow); lpRow = NULL; WC_MAPI(lpTable->QueryRows( 50, NULL, &lpRow)); if (FAILED(hRes) || !lpRow || !lpRow->cRows) break; for (i = 0; i < lpRow->cRows; i++) { hRes = S_OK; // Don't look at search folders if (PR_FOLDER_TYPE == lpRow->aRow[i].lpProps[ePR_FOLDER_TYPE].ulPropTag && FOLDER_SEARCH == lpRow->aRow[i].lpProps[ePR_FOLDER_TYPE].Value.ul) { continue; } if (PR_ENTRYID == lpRow->aRow[i].lpProps[ePR_ENTRYID].ulPropTag) { ULONG ulObjType = NULL; LPMAPIFOLDER lpSubfolder = NULL; WC_MAPI(lpFolder->OpenEntry(lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.cb, (LPENTRYID)lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.lpb, NULL, MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN *) &lpSubfolder)); if (SUCCEEDED(hRes) && lpSubfolder) { LPWSTR szDisplayName = L""; if (PR_DISPLAY_NAME_W == lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].ulPropTag) { szDisplayName = lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].Value.lpszW; } ullSize += ComputeFolderSize(lpszProfile, lpSubfolder, 0, szDisplayName); } if (lpSubfolder) lpSubfolder->Release(); } } } if (lpRow) FreeProws(lpRow); } if (lpTable) lpTable->Release(); return ullSize; } return 0; } // ComputeFolderSize
void DumpHierarchyTable( _In_z_ LPWSTR lpszProfile, _In_ LPMAPIFOLDER lpFolder, _In_ ULONG ulFolder, _In_z_ LPWSTR lpszFolder, _In_ ULONG ulDepth) { if (0 == ulDepth) { DebugPrint(DBGGeneric,"DumpHierarchyTable: Outputting hierarchy table for folder %u / %ws from profile %ws \n", ulFolder, lpszFolder?lpszFolder:L"", lpszProfile); } HRESULT hRes = S_OK; if (lpFolder) { LPMAPITABLE lpTable = NULL; LPSRowSet lpRow = NULL; ULONG i = 0; enum { ePR_DISPLAY_NAME_W, ePR_ENTRYID, NUM_COLS }; static const SizedSPropTagArray(NUM_COLS, rgColProps) = { NUM_COLS, PR_DISPLAY_NAME_W, PR_ENTRYID, }; WC_MAPI(lpFolder->GetHierarchyTable(MAPI_DEFERRED_ERRORS, &lpTable)); if (SUCCEEDED(hRes) && lpTable) { WC_MAPI(lpTable->SetColumns((LPSPropTagArray)&rgColProps, TBL_ASYNC)); if (!FAILED(hRes)) for (;;) { hRes = S_OK; if (lpRow) FreeProws(lpRow); lpRow = NULL; WC_MAPI(lpTable->QueryRows( 50, NULL, &lpRow)); if (FAILED(hRes) || !lpRow || !lpRow->cRows) break; for (i = 0; i < lpRow->cRows; i++) { hRes = S_OK; if (ulDepth >= 1) { ULONG iTab = 0; for (iTab = 0; iTab < ulDepth; iTab++) { printf(" "); } } if (PR_DISPLAY_NAME_W == lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].ulPropTag) { printf("%ws\n",lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].Value.lpszW); } if (PR_ENTRYID == lpRow->aRow[i].lpProps[ePR_ENTRYID].ulPropTag) { ULONG ulObjType = NULL; LPMAPIFOLDER lpSubfolder = NULL; WC_MAPI(lpFolder->OpenEntry(lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.cb, (LPENTRYID)lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.lpb, NULL, MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN *) &lpSubfolder)); if (SUCCEEDED(hRes) && lpSubfolder) { DumpHierarchyTable(lpszProfile, lpSubfolder, 0, L"", ulDepth + 1); } if (lpSubfolder) lpSubfolder->Release(); } } } if (lpRow) FreeProws(lpRow); } if (lpTable) lpTable->Release(); } } // DumpHierarchyTable
// Finds an arbitrarily nested folder in the indicated store given its // path name. HRESULT HrMAPIFindFolderExW( _In_ LPMDB lpMDB, // Open message store _In_z_ LPCWSTR lpszFolderPath, // folder path _Out_opt_ ULONG* lpcbeid, // pointer to count of bytes in entry ID _Deref_out_opt_ LPENTRYID* lppeid) // pointer to entry ID pointer { DebugPrint(DBGGeneric,"HrMAPIFindFolderExW: Locating path \"%ws\"\n", lpszFolderPath); HRESULT hRes = S_OK; LPMAPIFOLDER lpRootFolder = NULL; ULONG cbeid = 0; LPENTRYID lpeid = NULL; if (!lpcbeid || !lppeid) return MAPI_E_INVALID_PARAMETER; *lpcbeid = 0; *lppeid = NULL; if (!lpMDB) return MAPI_E_INVALID_PARAMETER; ULONG ulFolderCount = 0; LPWSTR* lppszFolderList = NULL; WC_H(HrSplitPath(lpszFolderPath, &ulFolderCount, &lppszFolderList)); // Check for literal property name if (ulFolderCount && lppszFolderList && lppszFolderList[0] && lppszFolderList[0][0] == L'@') { WC_H(HrLookupRootFolderW(lpMDB, lppszFolderList[0]+1, &cbeid, &lpeid)); if (SUCCEEDED(hRes)) { ulFolderCount--; if (ulFolderCount) { lppszFolderList = &lppszFolderList[1]; } } else { // Can we handle the case where one of our constants like DEFAULT_CALENDAR was passed? // We can parse the constant and call OpenDefaultFolder, then later not call OpenEntry for the root } } // If we have any subfolders, chase them if (SUCCEEDED(hRes) && ulFolderCount) { ULONG ulObjType = 0; WC_MAPI(lpMDB->OpenEntry( cbeid, lpeid, NULL, MAPI_BEST_ACCESS | MAPI_DEFERRED_ERRORS, &ulObjType, (LPUNKNOWN*)&lpRootFolder)); if (SUCCEEDED(hRes) && MAPI_FOLDER == ulObjType) { // Free before re-use MAPIFreeBuffer(lpeid); // Find the subfolder in question WC_H(HrMAPIFindSubfolderExW( lpRootFolder, ulFolderCount, lppszFolderList, &cbeid, &lpeid)); } if (lpRootFolder) lpRootFolder->Release(); } if (SUCCEEDED(hRes)) { *lpcbeid = cbeid; *lppeid = lpeid; } MAPIFreeBuffer(lppszFolderList); return hRes; } // HrMAPIFindFolderExW
// Finds an arbitrarily nested folder in the indicated folder given // a hierarchical list of subfolders. HRESULT HrMAPIFindSubfolderExW( _In_ LPMAPIFOLDER lpRootFolder, // open root folder ULONG ulFolderCount, // count of hierarchical list of subfolders to navigate LPWSTR* lppszFolderList, // hierarchical list of subfolders to navigate _Out_opt_ ULONG* lpcbeid, // pointer to count of bytes in entry ID _Deref_out_opt_ LPENTRYID* lppeid) // pointer to entry ID pointer { HRESULT hRes = S_OK; LPMAPIFOLDER lpParentFolder = lpRootFolder; LPMAPIFOLDER lpChildFolder = NULL; ULONG cbeid = 0; LPENTRYID lpeid = NULL; ULONG ulObjType = 0; ULONG i = 0; if (!lpcbeid || !lppeid) return MAPI_E_INVALID_PARAMETER; if (!ulFolderCount || !lppszFolderList) return MAPI_E_INVALID_PARAMETER; for (i = 0; i < ulFolderCount; i++) { // Free entryid before re-use. MAPIFreeBuffer(lpeid); WC_H(HrMAPIFindFolderW(lpParentFolder, lppszFolderList[i], &cbeid, &lpeid)); if (FAILED(hRes)) break; // Only OpenEntry if needed for next tier of folder path. if (lppszFolderList[i+1] != NULL) { WC_MAPI(lpParentFolder->OpenEntry( cbeid, lpeid, NULL, MAPI_DEFERRED_ERRORS, &ulObjType, (LPUNKNOWN*)&lpChildFolder)); if (FAILED(hRes) || ulObjType != MAPI_FOLDER) { MAPIFreeBuffer(lpeid); hRes = MAPI_E_CALL_FAILED; break; } } // No longer need the parent folder // (Don't release the folder that was passed!) if (i > 0) { if (lpParentFolder) lpParentFolder->Release(); } lpParentFolder = lpChildFolder; lpChildFolder = NULL; } // Success! *lpcbeid = cbeid; *lppeid = lpeid; return hRes; } // HrMAPIFindSubfolderExW
wstring MAPIFolder::FindFolderPath() { // return if no session object to compare ids if (!m_session) return L""; HRESULT hr = S_OK; ULONG ulResult = FALSE; wstring wstrPath = m_displayname; LPSPropValue pPropVal = NULL; ULONG ulType = 0; LPMAPIFOLDER lpMAPIFolder = NULL; SBinary prevEntryID = { 0 }; // Make copy of prev EntryID CopyEntryID(m_EntryID, prevEntryID); // Get parent ENTRYID if (SUCCEEDED(hr = HrGetOneProp(m_folder, PR_PARENT_ENTRYID, &pPropVal))) { while (!ulResult) { // compare entryID with previous m_session->CompareEntryIDs(&prevEntryID, &pPropVal->Value.bin, ulResult); // Free PrevEntryID FreeEntryID(prevEntryID); if (ulResult) { if (pPropVal) MAPIFreeBuffer(pPropVal); continue; } // Get Parent MAPI Folder if (SUCCEEDED(hr = m_session->OpenEntry(pPropVal->Value.bin.cb, (LPENTRYID)pPropVal->Value.bin.lpb, NULL, 0, &ulType, (LPUNKNOWN *)&lpMAPIFolder))) { // Get parent folder name LPSPropValue pDisplayPropVal = NULL; if (SUCCEEDED(hr = HrGetOneProp(lpMAPIFolder, PR_DISPLAY_NAME, &pDisplayPropVal))) { std::wstring tempath = pDisplayPropVal->Value.lpszW; // need to parse the parent folder names for forward slash std::wstring::size_type i = tempath.find(L"/"); while (i != std::wstring::npos && i < tempath.size()) { tempath.replace(i, wcslen(L"/"),CONST_FORWDSLASH); i += wcslen(L"/"); i = tempath.find( L"/", i); } //wstrPath = wstrPath + L"/" + pDisplayPropVal->Value.lpszW; wstrPath = wstrPath + L"/" + tempath; MAPIFreeBuffer(pDisplayPropVal); pDisplayPropVal = NULL; } // Make copy of prev EntryID CopyEntryID(pPropVal->Value.bin, prevEntryID); // free parent folder entryID MAPIFreeBuffer(pPropVal); pPropVal = NULL; // Get parent's parent entry ID if (!SUCCEEDED(hr = HrGetOneProp(lpMAPIFolder, PR_PARENT_ENTRYID, &pPropVal))) ulResult = TRUE; // free parent folder lpMAPIFolder->Release(); lpMAPIFolder = NULL; } else { ulResult = TRUE; } } } wstrPath = Zimbra::MAPI::Util::ReverseDelimitedString(wstrPath, L"/"); if (wstrPath.length() > 2) { size_t npos = wstrPath.find('/', 1); if (npos != std::string::npos) { wstrPath.replace(1, (npos-1), L"MAPIRoot"); } } //check for any earlier masking of "/" and restore it /* size_t cnst_pos = wstrPath.find(CONST_FORWDSLASH); if(std::wstring::npos != cnst_pos) { wstrPath.replace(cnst_pos,wcslen(CONST_FORWDSLASH),L"/"); } */ std::wstring::size_type i = wstrPath.find(CONST_FORWDSLASH); while (i != std::wstring::npos && i < wstrPath.size()) { wstrPath.replace(i, wcslen(CONST_FORWDSLASH), L"/"); i += wcslen(L"/"); i = wstrPath.find( CONST_FORWDSLASH, i); } return wstrPath; }