diff options
Diffstat (limited to 'mailnews/import/oexpress/WabObject.cpp')
-rw-r--r-- | mailnews/import/oexpress/WabObject.cpp | 1132 |
1 files changed, 1132 insertions, 0 deletions
diff --git a/mailnews/import/oexpress/WabObject.cpp b/mailnews/import/oexpress/WabObject.cpp new file mode 100644 index 000000000..e206b74f8 --- /dev/null +++ b/mailnews/import/oexpress/WabObject.cpp @@ -0,0 +1,1132 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <tchar.h> +#include "nscore.h" +#include "nsOE5File.h" +#include "wabobject.h" +#include <algorithm> + +enum { + ieidPR_DISPLAY_NAME = 0, + ieidPR_ENTRYID, + ieidPR_OBJECT_TYPE, + ieidMax +}; + +static const SizedSPropTagArray(ieidMax, ptaEid)= +{ + ieidMax, + { + PR_DISPLAY_NAME, + PR_ENTRYID, + PR_OBJECT_TYPE, + } +}; + + +enum { + iemailPR_DISPLAY_NAME = 0, + iemailPR_ENTRYID, + iemailPR_EMAIL_ADDRESS, + iemailPR_OBJECT_TYPE, + iemailMax +}; +static const SizedSPropTagArray(iemailMax, ptaEmail)= +{ + iemailMax, + { + PR_DISPLAY_NAME, + PR_ENTRYID, + PR_EMAIL_ADDRESS, + PR_OBJECT_TYPE + } +}; + +typedef struct { + bool multiLine; + ULONG tag; + char * pLDIF; +} AddrImportField; + +#define kExtraUserFields 10 +AddrImportField extraUserFields[kExtraUserFields] = { + {true, PR_COMMENT, "description:"}, + {false, PR_BUSINESS_TELEPHONE_NUMBER, "telephonenumber:"}, + {false, PR_HOME_TELEPHONE_NUMBER, "homephone:"}, + {false, PR_COMPANY_NAME, "o:"}, + {false, PR_TITLE, "title:"}, + {false, PR_BUSINESS_FAX_NUMBER, "facsimiletelephonenumber:"}, + {false, PR_LOCALITY, "locality:"}, + {false, PR_STATE_OR_PROVINCE, "st:"}, + {true, PR_STREET_ADDRESS, "streetaddress:"}, + {false, PR_POSTAL_CODE, "postalcode:"} +}; + +#define kWhitespace " \t\b\r\n" + +#define TR_OUTPUT_EOL "\r\n" + +#define kLDIFPerson "objectclass: top" TR_OUTPUT_EOL "objectclass: person" TR_OUTPUT_EOL +#define kLDIFGroup "objectclass: top" TR_OUTPUT_EOL "objectclass: groupOfNames" TR_OUTPUT_EOL + +/*********************************************************************************/ + + +// contructor for CWAB object +// +// pszFileName - FileName of WAB file to open +// if no file name is specified, opens the default +// +CWAB::CWAB(nsIFile *file) +{ + // Here we load the WAB Object and initialize it + m_pUniBuff = NULL; + m_uniBuffLen = 0; + + m_bInitialized = false; + m_lpAdrBook = NULL; + m_lpWABObject = NULL; + m_hinstWAB = NULL; + + { + TCHAR szWABDllPath[MAX_PATH]; + DWORD dwType = 0; + ULONG cbData = sizeof(szWABDllPath); + HKEY hKey = NULL; + + *szWABDllPath = '\0'; + + // First we look under the default WAB DLL path location in the + // Registry. + // WAB_DLL_PATH_KEY is defined in wabapi.h + // + if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey)) { + RegQueryValueEx(hKey, "", NULL, &dwType, (LPBYTE) szWABDllPath, &cbData); + if (dwType == REG_EXPAND_SZ) { + // Expand the environment variables + DWORD bufferSize = ExpandEnvironmentStrings(szWABDllPath, NULL, 0); + if (bufferSize && bufferSize < MAX_PATH) { + TCHAR tmp[MAX_PATH]; + ExpandEnvironmentStrings(szWABDllPath, tmp, bufferSize); + _tcscpy(szWABDllPath, tmp); + } + else { + // This is an error condition. Nothing else is initialized yet, so simply return. + return; + } + + } + } + else { + if (GetSystemDirectory(szWABDllPath, MAX_PATH)) { + _tcsncat(szWABDllPath, WAB_DLL_NAME, + std::min(_tcslen(WAB_DLL_NAME), MAX_PATH - _tcslen(szWABDllPath) - 1)); + } + else { + // Yet another error condition. + return; + } + } + + if(hKey) RegCloseKey(hKey); + + // if the Registry came up blank, we do a loadlibrary on the wab32.dll + // WAB_DLL_NAME is defined in wabapi.h + // + m_hinstWAB = LoadLibrary((lstrlen(szWABDllPath)) ? szWABDllPath : WAB_DLL_NAME); + } + + if(m_hinstWAB) + { + // if we loaded the dll, get the entry point + // + m_lpfnWABOpen = (LPWABOPEN) GetProcAddress(m_hinstWAB, "WABOpen"); + + if(m_lpfnWABOpen) + { + char fName[2] = {0, 0}; + HRESULT hr = E_FAIL; + WAB_PARAM wp = {0}; + wp.cbSize = sizeof(WAB_PARAM); + if (file != nullptr) { + nsCString path; + file->GetNativePath(path); + wp.szFileName = (LPTSTR) ToNewCString(path); + } + else + wp.szFileName = (LPTSTR) fName; + + // if we choose not to pass in a WAB_PARAM object, + // the default WAB file will be opened up + // + hr = m_lpfnWABOpen(&m_lpAdrBook,&m_lpWABObject,&wp,0); + + if(!hr) + m_bInitialized = TRUE; + + } + } + +} + + +// Destructor +// +CWAB::~CWAB() +{ + if (m_pUniBuff) + delete [] m_pUniBuff; + + if(m_bInitialized) + { + if(m_lpAdrBook) + m_lpAdrBook->Release(); + + if(m_lpWABObject) + m_lpWABObject->Release(); + + if(m_hinstWAB) + FreeLibrary(m_hinstWAB); + } +} + + +HRESULT CWAB::IterateWABContents(CWabIterator *pIter, int *pDone) +{ + if (!m_bInitialized || !m_lpAdrBook) + return E_FAIL; + + ULONG ulObjType = 0; + LPMAPITABLE lpAB = NULL; + ULONG cRows = 0; + LPSRowSet lpRowAB = NULL; + LPABCONT lpContainer = NULL; + int cNumRows = 0; + nsresult keepGoing; + + HRESULT hr = E_FAIL; + + ULONG lpcbEID = 0; + LPENTRYID lpEID = NULL; + ULONG rowCount = 0; + ULONG curCount = 0; + + nsString uniStr; + + // Get the entryid of the root PAB container + // + hr = m_lpAdrBook->GetPAB(&lpcbEID, &lpEID); + + if (HR_FAILED(hr)) + goto exit; + + ulObjType = 0; + + // Open the root PAB container + // This is where all the WAB contents reside + // + hr = m_lpAdrBook->OpenEntry(lpcbEID, + (LPENTRYID)lpEID, + NULL, + 0, + &ulObjType, + (LPUNKNOWN *)&lpContainer); + + m_lpWABObject->FreeBuffer(lpEID); + + lpEID = NULL; + + if(HR_FAILED(hr)) + goto exit; + + // Get a contents table of all the contents in the + // WABs root container + // + hr = lpContainer->GetContentsTable(0, &lpAB); + + if(HR_FAILED(hr)) + goto exit; + + hr = lpAB->GetRowCount(0, &rowCount); + if (HR_FAILED(hr)) + rowCount = 100; + if (rowCount == 0) + rowCount = 1; + + // Order the columns in the ContentsTable to conform to the + // ones we want - which are mainly DisplayName, EntryID and + // ObjectType + // The table is gauranteed to set the columns in the order + // requested + // + hr =lpAB->SetColumns((LPSPropTagArray)&ptaEid, 0); + + if(HR_FAILED(hr)) + goto exit; + + + // Reset to the beginning of the table + // + hr = lpAB->SeekRow(BOOKMARK_BEGINNING, 0, NULL); + + if(HR_FAILED(hr)) + goto exit; + + // Read all the rows of the table one by one + // + + do { + + hr = lpAB->QueryRows(1, 0, &lpRowAB); + + if(HR_FAILED(hr)) + break; + + if(lpRowAB) + { + cNumRows = lpRowAB->cRows; + + if (cNumRows) + { + LPTSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA; + LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; + ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; + + // There are 2 kinds of objects - the MAPI_MAILUSER contact object + // and the MAPI_DISTLIST contact object + // For the purposes of this sample, we will only consider MAILUSER + // objects + // + if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER) + { + // We will now take the entry-id of each object and cache it + // on the listview item representing that object. This enables + // us to uniquely identify the object later if we need to + // + CStrToUnicode(lpsz, uniStr); + keepGoing = pIter->EnumUser(uniStr.get(), lpEID, cbEID); + curCount++; + if (pDone) { + *pDone = (curCount * 100) / rowCount; + if (*pDone > 100) + *pDone = 100; + } + } + } + FreeProws(lpRowAB); + } + + + } while (SUCCEEDED(hr) && cNumRows && lpRowAB && NS_SUCCEEDED(keepGoing)) ; + + hr = lpAB->SeekRow(BOOKMARK_BEGINNING, 0, NULL); + + if(HR_FAILED(hr)) + goto exit; + + // Read all the rows of the table one by one + // + keepGoing = NS_OK; + do { + + hr = lpAB->QueryRows(1, 0, &lpRowAB); + + if(HR_FAILED(hr)) + break; + + if(lpRowAB) + { + cNumRows = lpRowAB->cRows; + + if (cNumRows) + { + LPTSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA; + LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; + ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; + + // There are 2 kinds of objects - the MAPI_MAILUSER contact object + // and the MAPI_DISTLIST contact object + // For the purposes of this sample, we will only consider MAILUSER + // objects + // + if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_DISTLIST) + { + LPABCONT distListContainer = NULL; + // We will now take the entry-id of each object and cache it + // on the listview item representing that object. This enables + // us to uniquely identify the object later if we need to + // + hr = m_lpAdrBook->OpenEntry(cbEID, lpEID, NULL, + 0,&ulObjType,(LPUNKNOWN *)&distListContainer); + + LPMAPITABLE distListTable = NULL; + + + // Get a contents table of the dist list + // + hr = distListContainer->GetContentsTable(0, &distListTable); + if (lpAB) + { + hr = distListTable->GetRowCount(0, &rowCount); + if (HR_FAILED(hr)) + rowCount = 100; + if (rowCount == 0) + rowCount = 1; + + // Order the columns in the ContentsTable to conform to the + // ones we want - which are mainly DisplayName, EntryID and + // ObjectType + // The table is gauranteed to set the columns in the order + // requested + // + hr = distListTable->SetColumns((LPSPropTagArray)&ptaEid, 0); + CStrToUnicode(lpsz, uniStr); + keepGoing = pIter->EnumList(uniStr.get(), lpEID, cbEID, distListTable); + curCount++; + if (pDone) { + *pDone = (curCount * 100) / rowCount; + if (*pDone > 100) + *pDone = 100; + } + } + if (distListContainer) + distListContainer->Release(); + if (distListTable) + distListTable->Release(); + } + } + FreeProws(lpRowAB); + } + + } while (SUCCEEDED(hr) && cNumRows && lpRowAB && NS_SUCCEEDED(keepGoing)) ; + + +exit: + + if (lpContainer) + lpContainer->Release(); + + if (lpAB) + lpAB->Release(); + + return hr; +} + + + + + + +void CWAB::FreeProws(LPSRowSet prows) +{ + ULONG irow; + if (!prows) + return; + for (irow = 0; irow < prows->cRows; ++irow) + m_lpWABObject->FreeBuffer(prows->aRow[irow].lpProps); + m_lpWABObject->FreeBuffer(prows); +} + + +LPDISTLIST CWAB::GetDistList(ULONG cbEid, LPENTRYID pEid) +{ + if (!m_bInitialized || !m_lpAdrBook) + return NULL; + + LPDISTLIST lpDistList = NULL; + ULONG ulObjType; + + m_lpAdrBook->OpenEntry(cbEid, pEid, NULL, 0, &ulObjType, (LPUNKNOWN *)&lpDistList); + return lpDistList; +} + +LPSPropValue CWAB::GetListProperty(LPDISTLIST pUser, ULONG tag) +{ + if (!pUser) + 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 = pUser->GetProps(pTag, 0, &cValues, &lpProp); + delete [] pTag; + if (HR_FAILED(hr) || (cValues != 1)) { + if (lpProp) + m_lpWABObject->FreeBuffer(lpProp); + return NULL; + } + return lpProp; +} + +LPMAILUSER CWAB::GetUser(ULONG cbEid, LPENTRYID pEid) +{ + if (!m_bInitialized || !m_lpAdrBook) + return NULL; + + LPMAILUSER lpMailUser = NULL; + ULONG ulObjType; + + m_lpAdrBook->OpenEntry(cbEid, pEid, NULL, 0, &ulObjType, (LPUNKNOWN *)&lpMailUser); + return lpMailUser; +} + +LPSPropValue CWAB::GetUserProperty(LPMAILUSER pUser, ULONG tag) +{ + if (!pUser) + return NULL; + + ULONG uTag = tag; + /* + Getting Unicode does not help with getting the right + international charset. Windoze bloze. + */ + /* + if (PROP_TYPE(uTag) == PT_STRING8) { + uTag = CHANGE_PROP_TYPE(tag, PT_UNICODE); + } + */ + + int sz = CbNewSPropTagArray(1); + SPropTagArray *pTag = (SPropTagArray *) new char[sz]; + pTag->cValues = 1; + pTag->aulPropTag[0] = uTag; + LPSPropValue lpProp = NULL; + ULONG cValues = 0; + HRESULT hr = pUser->GetProps(pTag, 0, &cValues, &lpProp); + if (HR_FAILED(hr) || (cValues != 1)) { + if (lpProp) + m_lpWABObject->FreeBuffer(lpProp); + lpProp = NULL; + if (uTag != tag) { + pTag->cValues = 1; + pTag->aulPropTag[0] = tag; + cValues = 0; + hr = pUser->GetProps(pTag, 0, &cValues, &lpProp); + if (HR_FAILED(hr) || (cValues != 1)) { + if (lpProp) + m_lpWABObject->FreeBuffer(lpProp); + lpProp = NULL; + } + } + } + delete [] pTag; + return lpProp; +} + +void CWAB::CStrToUnicode(const char *pStr, nsString& result) +{ + result.Truncate(); + int wLen = MultiByteToWideChar(CP_ACP, 0, pStr, -1, wwc(m_pUniBuff), 0); + if (wLen >= m_uniBuffLen) { + if (m_pUniBuff) + delete [] m_pUniBuff; + m_pUniBuff = new char16_t[wLen + 64]; + m_uniBuffLen = wLen + 64; + } + if (wLen) { + MultiByteToWideChar(CP_ACP, 0, pStr, -1, wwc(m_pUniBuff), m_uniBuffLen); + result = m_pUniBuff; + } +} + +// If the value is a string, get it... +void CWAB::GetValueString(LPSPropValue pVal, nsString& val) +{ + val.Truncate(); + + if (!pVal) + return; + + switch(PROP_TYPE(pVal->ulPropTag)) { + case PT_STRING8: + CStrToUnicode((const char *) (pVal->Value.lpszA), val); + break; + case PT_UNICODE: + val = (char16_t *) (pVal->Value.lpszW); + break; + case PT_MV_STRING8: { + nsString tmp; + ULONG j; + for(j = 0; j < pVal->Value.MVszA.cValues; j++) { + CStrToUnicode((const char *) (pVal->Value.MVszA.lppszA[j]), tmp); + val += tmp; + val.Append(NS_ConvertASCIItoUTF16(TR_OUTPUT_EOL)); + } + break; + } + case PT_MV_UNICODE: { + ULONG j; + for(j = 0; j < pVal->Value.MVszW.cValues; j++) { + val += (char16_t *) (pVal->Value.MVszW.lppszW[j]); + val.Append(NS_ConvertASCIItoUTF16(TR_OUTPUT_EOL)); + } + break; + } + case PT_I2: + case PT_LONG: + case PT_R4: + case PT_DOUBLE: + case PT_BOOLEAN: { + /* + TCHAR sz[256]; + wsprintf(sz,"%d", pVal->Value.l); + val = sz; + */ + break; + } + + case PT_BINARY: + break; + + default: + break; + } + + val.Trim(kWhitespace, true, true); +} + + +void CWAB::GetValueTime(LPSPropValue pVal, PRTime& val) +{ + if (!pVal) + return; + + if (PROP_TYPE(pVal->ulPropTag) != PT_SYSTIME) + return; + + nsOE5File::FileTimeToPRTime(&pVal->Value.ft, &val); +} + +bool CWAB::IsAvailable() +{ + if (!m_bInitialized || !m_lpAdrBook) + return false; + + ULONG lpcbEID = 0; + LPENTRYID lpEID = NULL; + HRESULT hr = m_lpAdrBook->GetPAB(&lpcbEID, &lpEID); + if (HR_FAILED(hr)) + return false; + + ULONG ulObjType = 0; + LPABCONT lpContainer = NULL; + hr = m_lpAdrBook->OpenEntry(lpcbEID, + (LPENTRYID)lpEID, + NULL, + 0, + &ulObjType, + (LPUNKNOWN *)&lpContainer); + m_lpWABObject->FreeBuffer(lpEID); + + LPMAPITABLE lpAB = NULL; + hr = lpContainer->GetContentsTable(0, &lpAB); + if(HR_FAILED(hr)) { + lpContainer->Release(); + return false; + } + + ULONG rowCount = 0; + hr = lpAB->GetRowCount(0, &rowCount); + lpContainer->Release(); + lpAB->Release(); + return (rowCount != 0); +} + +/* +BOOL CWabIterateProcess::SanitizeMultiLine(CString& val) +{ + val.TrimLeft(); + val.TrimRight(); + int idx = val.FindOneOf("\x0D\x0A"); + if (idx == -1) + return FALSE; + + // needs encoding + U32 bufSz = UMimeEncode::GetBufferSize(val.GetLength()); + P_U8 pBuf = new U8[bufSz]; + U32 len = UMimeEncode::ConvertBuffer((PC_U8)((PC_S8)val), val.GetLength(), pBuf, 66, 52, "\x0D\x0A "); + pBuf[len] = 0; + val = pBuf; + delete pBuf; + return TRUE; +} + +BOOL CWabIterateProcess::EnumUser(LPCTSTR pName, LPENTRYID pEid, ULONG cbEid) +{ + TRACE1("User: %s\n", pName); + + LPMAILUSER pUser = m_pWab->GetUser(cbEid, pEid); + + // Get the "required" strings first + CString lastName; + CString firstName; + CString eMail; + CString nickName; + CString middleName; + + if (!pUser) { + UDialogs::ErrMessage1(IDS_ENTRY_ERROR, pName); + return FALSE; + } + + LPSPropValue pProp = m_pWab->GetUserProperty(pUser, PR_EMAIL_ADDRESS); + if (pProp) { + m_pWab->GetValueString(pProp, eMail); + SanitizeValue(eMail); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_GIVEN_NAME); + if (pProp) { + m_pWab->GetValueString(pProp, firstName); + SanitizeValue(firstName); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_SURNAME); + if (pProp) { + m_pWab->GetValueString(pProp, lastName); + SanitizeValue(lastName); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_MIDDLE_NAME); + if (pProp) { + m_pWab->GetValueString(pProp, middleName); + SanitizeValue(middleName); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_NICKNAME); + if (pProp) { + m_pWab->GetValueString(pProp, nickName); + SanitizeValue(nickName); + m_pWab->FreeProperty(pProp); + } + if (nickName.IsEmpty()) + nickName = pName; + if (firstName.IsEmpty()) { + firstName = nickName; + middleName.Empty(); + lastName.Empty(); + } + if (lastName.IsEmpty()) + middleName.Empty(); + + if (eMail.IsEmpty()) + eMail = nickName; + + + // We now have the required fields + // write them out followed by any optional fields! + BOOL result = TRUE; + + if (m_recordsDone) + result = m_out.WriteEol(); + + CString line; + CString header; + line.LoadString(IDS_LDIF_DN_START); + line += firstName; + if (!middleName.IsEmpty()) { + line += ' '; + line += middleName; + } + if (!lastName.IsEmpty()) { + line += ' '; + line += lastName; + } + header.LoadString(IDS_LDIF_DN_MIDDLE); + line += header; + line += eMail; + result = result && m_out.WriteStr(line); + result = result && m_out.WriteEol(); + + line.LoadString(IDS_FIELD_LDIF_FULLNAME); + line += ' '; + line += firstName; + if (!middleName.IsEmpty()) { + line += ' '; + line += middleName; + } + if (!lastName.IsEmpty()) { + line += ' '; + line += lastName; + } + result = result && m_out.WriteStr(line); + result = result && m_out.WriteEol(); + + + line.LoadString(IDS_FIELD_LDIF_GIVENNAME); + line += ' '; + line += firstName; + result = result && m_out.WriteStr(line); + result = result && m_out.WriteEol(); + + if (!lastName.IsEmpty()) { + line.LoadString(IDS_FIELD_LDIF_LASTNAME); + if (!middleName.IsEmpty()) { + line += ' '; + line += middleName; + } + line += ' '; + line += lastName; + result = result && m_out.WriteStr(line); + result = result && m_out.WriteEol(); + } + + result = result && m_out.WriteStr(kLDIFPerson); + + line.LoadString(IDS_FIELD_LDIF_EMAIL); + line += ' '; + line += eMail; + result = result && m_out.WriteStr(line); + result = result && m_out.WriteEol(); + + line.LoadString(IDS_FIELD_LDIF_NICKNAME); + line += ' '; + line += nickName; + result = result && m_out.WriteStr(line); + result = result && m_out.WriteEol(); + + // Do all of the extra fields! + CString value; + BOOL encoded = FALSE; + for (int i = 0; i < kExtraUserFields; i++) { + value.Empty(); + pProp = m_pWab->GetUserProperty(pUser, extraUserFields[i].tag); + if (pProp) { + m_pWab->GetValueString(pProp, value); + m_pWab->FreeProperty(pProp); + } + if (extraUserFields[i].multiLine) { + encoded = SanitizeMultiLine(value); + } + else + SanitizeValue(value); + if (!value.IsEmpty()) { + line = extraUserFields[i].pLDIF; + if (encoded) { + line += ": "; + encoded = FALSE; + } + else + line += ' '; + line += value; + result = result && m_out.WriteStr(line); + result = result && m_out.WriteEol(); + } + } + + m_pWab->ReleaseUser(pUser); + + if (!result) { + UDialogs::ErrMessage0(IDS_ADDRESS_SAVE_ERROR); + } + + m_totalDone += kValuePerUser; + m_recordsDone++; + + return result; +} +*/ + + + + +/* +BOOL CWabIterateProcess::EnumList(LPCTSTR pName, LPENTRYID pEid, ULONG cbEid) +{ + TRACE1("List: %s\n", pName); + + LPDISTLIST pList = m_pWab->GetDistList(cbEid, pEid); + if (!pList) { + UDialogs::ErrMessage1(IDS_ENTRY_ERROR, pName); + return FALSE; + } + + // Find out if this is just a regular entry or a true list... + CString eMail; + LPSPropValue pProp = m_pWab->GetListProperty(pList, PR_EMAIL_ADDRESS); + if (pProp) { + m_pWab->GetValueString(pProp, eMail); + SanitizeValue(eMail); + m_pWab->FreeProperty(pProp); + // Treat this like a regular entry... + if (!eMail.IsEmpty()) { + m_pWab->ReleaseDistList(pList); + return WriteListUserEntry(pName, eMail); + } + } + + // This may very well be a list, find the entries... + m_pListTable = OpenDistList(pList); + if (m_pListTable) { + m_pList = pList; + m_listName = pName; + m_listDone = 0; + m_listHeaderDone = FALSE; + m_state = kEnumListState; + } + else { + m_pWab->ReleaseDistList(pList); + m_recordsDone++; + m_totalDone += kValuePerUser; + } + + return TRUE; +} + +BOOL CWabIterateProcess::EnumNextListUser(BOOL *pDone) +{ + HRESULT hr; + int cNumRows = 0; + LPSRowSet lpRowAB = NULL; + BOOL keepGoing = TRUE; + + if (!m_pListTable) + return FALSE; + + hr = m_pListTable->QueryRows(1, 0, &lpRowAB); + + if(HR_FAILED(hr)) { + UDialogs::ErrMessage0(IDS_ERROR_READING_WAB); + return FALSE; + } + + if(lpRowAB) { + cNumRows = lpRowAB->cRows; + + if (cNumRows) { + LPTSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA; + LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; + ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; + if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_DISTLIST) { + keepGoing = HandleListList(lpsz, lpEID, cbEID); + } + else if (lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER) { + keepGoing = HandleListUser(lpsz, lpEID, cbEID); + } + } + m_pWab->FreeProws(lpRowAB); + } + + if (!cNumRows || !lpRowAB) { + *pDone = TRUE; + m_pListTable->Release(); + m_pListTable = NULL; + if (m_pList) + m_pWab->ReleaseDistList(m_pList); + m_pList = NULL; + if (m_listDone < kValuePerUser) + m_totalDone += (kValuePerUser - m_listDone); + m_recordsDone++; + return keepGoing; + } + + if (!keepGoing) + return FALSE; + + if (m_listDone < kValuePerUser) { + m_listDone++; + m_totalDone++; + } + + return TRUE; +} + +BOOL CWabIterateProcess::HandleListList(LPCTSTR pName, LPENTRYID lpEid, ULONG cbEid) +{ + BOOL result; + LPDISTLIST pList = m_pWab->GetDistList(cbEid, lpEid); + if (!pList) { + UDialogs::ErrMessage1(IDS_ENTRY_ERROR, pName); + return FALSE; + } + + CString eMail; + LPSPropValue pProp = m_pWab->GetListProperty(pList, PR_EMAIL_ADDRESS); + if (pProp) { + m_pWab->GetValueString(pProp, eMail); + SanitizeValue(eMail); + m_pWab->FreeProperty(pProp); + // Treat this like a regular entry... + if (!eMail.IsEmpty()) { + // write out a member based on pName and eMail + result = WriteGroupMember(pName, eMail); + m_pWab->ReleaseDistList(pList); + return result; + } + } + + // iterate the list and add each member to the top level list + LPMAPITABLE pTable = OpenDistList(pList); + if (!pTable) { + TRACE0("Error opening table for list\n"); + m_pWab->ReleaseDistList(pList); + UDialogs::ErrMessage1(IDS_ENTRY_ERROR, pName); + return FALSE; + } + + int cNumRows = 0; + LPSRowSet lpRowAB = NULL; + HRESULT hr; + BOOL keepGoing = TRUE; + + do { + hr = pTable->QueryRows(1, 0, &lpRowAB); + + if(HR_FAILED(hr)) { + UDialogs::ErrMessage0(IDS_ERROR_READING_WAB); + pTable->Release(); + m_pWab->ReleaseDistList(pList); + return FALSE; + } + + if(lpRowAB) { + cNumRows = lpRowAB->cRows; + + if (cNumRows) { + LPTSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA; + LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; + ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; + if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_DISTLIST) { + keepGoing = HandleListList(lpsz, lpEID, cbEID); + } + else if (lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER) { + keepGoing = HandleListUser(lpsz, lpEID, cbEID); + } + } + m_pWab->FreeProws(lpRowAB); + } + } + while (keepGoing && cNumRows && lpRowAB); + + pTable->Release(); + m_pWab->ReleaseDistList(pList); + return keepGoing; +} + +BOOL CWabIterateProcess::HandleListUser(LPCTSTR pName, LPENTRYID lpEid, ULONG cbEid) +{ + // Get the basic properties for building the member line + LPMAILUSER pUser = m_pWab->GetUser(cbEid, lpEid); + + // Get the "required" strings first + CString lastName; + CString firstName; + CString eMail; + CString nickName; + CString middleName; + + if (!pUser) { + UDialogs::ErrMessage1(IDS_ENTRY_ERROR, pName); + return FALSE; + } + + LPSPropValue pProp = m_pWab->GetUserProperty(pUser, PR_EMAIL_ADDRESS); + if (pProp) { + m_pWab->GetValueString(pProp, eMail); + SanitizeValue(eMail); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_GIVEN_NAME); + if (pProp) { + m_pWab->GetValueString(pProp, firstName); + SanitizeValue(firstName); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_SURNAME); + if (pProp) { + m_pWab->GetValueString(pProp, lastName); + SanitizeValue(lastName); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_MIDDLE_NAME); + if (pProp) { + m_pWab->GetValueString(pProp, middleName); + SanitizeValue(middleName); + m_pWab->FreeProperty(pProp); + } + pProp = m_pWab->GetUserProperty(pUser, PR_NICKNAME); + if (pProp) { + m_pWab->GetValueString(pProp, nickName); + SanitizeValue(nickName); + m_pWab->FreeProperty(pProp); + } + if (nickName.IsEmpty()) + nickName = pName; + if (firstName.IsEmpty()) { + firstName = nickName; + middleName.Empty(); + lastName.Empty(); + } + if (lastName.IsEmpty()) + middleName.Empty(); + + if (eMail.IsEmpty()) + eMail = nickName; + + m_pWab->ReleaseUser(pUser); + + CString name = firstName; + if (!middleName.IsEmpty()) { + name += ' '; + name += middleName; + } + if (!lastName.IsEmpty()) { + name += ' '; + name += lastName; + } + return WriteGroupMember(name, eMail); +} + +BOOL CWabIterateProcess::WriteGroupMember(const char *pName, const char *pEmail) +{ + CString middle; + CString line; + BOOL result; + + // Check for the header first + if (!m_listHeaderDone) { + if (m_recordsDone) + result = m_out.WriteEol(); + else + result = TRUE; + line.LoadString(IDS_LDIF_DN_START); + line += m_listName; + line += TR_OUTPUT_EOL; + middle.LoadString(IDS_FIELD_LDIF_FULLNAME); + line += middle; + line += m_listName; + line += TR_OUTPUT_EOL; + if (!result || !m_out.WriteStr(line) || !m_out.WriteStr(kLDIFGroup)) { + UDialogs::ErrMessage0(IDS_ADDRESS_SAVE_ERROR); + return FALSE; + } + m_listHeaderDone = TRUE; + } + + + line.LoadString(IDS_FIELD_LDIF_MEMBER_START); + line += pName; + middle.LoadString(IDS_LDIF_DN_MIDDLE); + line += middle; + line += pEmail; + line += TR_OUTPUT_EOL; + if (!m_out.WriteStr(line)) { + UDialogs::ErrMessage0(IDS_ADDRESS_SAVE_ERROR); + return FALSE; + } + + if (m_listDone < kValuePerUser) { + m_listDone++; + m_totalDone++; + } + + return TRUE; +} +*/ + |