Dactyloidae/mailnews/import/oexpress/WabObject.cpp

1132 lines
28 KiB
C++

/* -*- 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;
}
*/