|
|
/******************************************************************************
FILENAME: wabimp.c MODULE: DLL for PAB, CSV, NetScape, Eudora and Athena16 address book conversions. PURPOSE: Contains modules which will implement importing MAPI PAB, CSV, NetScape, Eudora and Athena16 address book to Athena32 (WAB).
EXPORTED FUNCTIONS: STDMETHODIMP NetscapeImport(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) STDMETHODIMP Athena16Import(HWND hwnd,LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) STDMETHODIMP EudoraImport(HWND hwnd,LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions)
Programmer(s): Arathi (NetQuest) Radhika (NetQuest) Krishnamoorthy SeethaRaman(NetQuest)
Revision History:
4/7/97 - vikramm Fix Bugs: Netscape Display Names not being imported. "Replace Import" dialog has no parent. 4/8/97 - vikramm Fix Bugs: Handle Leak. Add code to look for additional Eudora address books that may be in subdirectories ... 4/9/97 - vikramm Change the Eudora registry search path ... Fix Bugs: Looking in wrong reg Key for Netscape on NT and wrongly assuming key exists for pre netscape 3.0 Change dialog messages. *******************************************************************************/
//Includes
#define _WABIMP_C
#include "_comctl.h"
#include <windows.h>
#include <commctrl.h>
#include <mapix.h>
#include <wab.h>
#include <wabmig.h>
#include <wabguid.h>
#include <wabdbg.h>
#include <dbgutil.h>
#include "..\..\wab32res\resrc2.h"
#include <wabimp.h>
#include <string.h>
#include <advpub.h>
#include <shlwapi.h>
// Per-process Globals
TCHAR szGlobalAlloc[MAX_MESSAGE]; // Buffer used for LoadString
TCHAR szGlobalTempAlloc[MAX_MESSAGE];
const TCHAR szTextFilter[] = "*.txt"; const TCHAR szAllFilter[] = "*.*";
const TCHAR szMSN[] = "MSN"; const TCHAR szMSNINET[] = "MSNINET"; const TCHAR szCOMPUSERVE[] = "COMPUSERVE"; const TCHAR szFAX[] = "FAX"; const TCHAR szSMTP[] = "SMTP"; const TCHAR szMS[] = "MS"; const TCHAR szEX[] = "EX"; const TCHAR szX400[] = "X400"; const TCHAR szMSA[] = "MSA"; const TCHAR szMAPIPDL[] = "MAPIPDL"; const TCHAR szEmpty[] = ""; const TCHAR szDescription[] = "description"; const TCHAR szDll[] = "dll"; const TCHAR szEntry[] = "entry"; const TCHAR szEXPORT[] = "EXPORT"; const TCHAR szIMPORT[] = "IMPORT";
const TCHAR szAtSign[] = "@"; const TCHAR szMSNpostfix[] = "@msn.com"; const TCHAR szCOMPUSERVEpostfix[] = "@compuserve.com"; LPENTRY_SEEN lpEntriesSeen = NULL; ULONG ulEntriesSeen = 0; ULONG ulMaxEntries = 0; const LPTSTR szWABKey = "Software\\Microsoft\\WAB"; LPTARGET_INFO rgTargetInfo = NULL;
HINSTANCE hInst = NULL; HINSTANCE hInstApp = NULL;
//
// Properties to get for each row of the contents table
//
const SizedSPropTagArray(iptaColumnsMax, ptaColumns) = { iptaColumnsMax, { PR_OBJECT_TYPE, PR_ENTRYID, PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, } };
const SizedSPropTagArray(ieidMax, ptaEid)= { ieidMax, { PR_ENTRYID, } };
const SizedSPropTagArray(iconMax, ptaCon)= { iconMax, { PR_DEF_CREATE_MAILUSER, PR_DEF_CREATE_DL, } };
// Global WAB Allocator access functions
//
typedef struct _WAB_ALLOCATORS { LPWABOBJECT lpWABObject; LPWABALLOCATEBUFFER lpAllocateBuffer; LPWABALLOCATEMORE lpAllocateMore; LPWABFREEBUFFER lpFreeBuffer; } WAB_ALLOCATORS, *LPWAB_ALLOCATORS;
WAB_ALLOCATORS WABAllocators = {0};
/******************************************************************************
Name : SetGlobalBufferFunctions
Purpose : Set the global buffer functions based on methods from the WAB object.
Parameters: lpWABObject = the open wab object
Returns : none
Comment :
******************************************************************************/ void SetGlobalBufferFunctions(LPWABOBJECT lpWABObject) { if (lpWABObject && ! WABAllocators.lpWABObject) { WABAllocators.lpAllocateBuffer = lpWABObject->lpVtbl->AllocateBuffer; WABAllocators.lpAllocateMore = lpWABObject->lpVtbl->AllocateMore; WABAllocators.lpFreeBuffer = lpWABObject->lpVtbl->FreeBuffer; WABAllocators.lpWABObject = lpWABObject; } }
/******************************************************************************
Name : WABAllocateBuffer
Purpose : Use the WAB Allocator
Parameters: cbSize = size to allocate lppBuffer = returned buffer
Returns : SCODE
Comment :
*******************************************************************************/ SCODE WABAllocateBuffer(ULONG cbSize, LPVOID FAR * lppBuffer) { if (WABAllocators.lpWABObject && WABAllocators.lpAllocateBuffer) { return(WABAllocators.lpAllocateBuffer(WABAllocators. lpWABObject, cbSize, lppBuffer)); } else { return(MAPI_E_INVALID_OBJECT); } }
/******************************************************************************
Name : WABAllocateMore
Purpose : Use the WAB Allocator
Parameters: cbSize = size to allocate lpObject = existing allocation lppBuffer = returned buffer
Returns : SCODE
Comment :
*******************************************************************************/ SCODE WABAllocateMore(ULONG cbSize, LPVOID lpObject, LPVOID FAR * lppBuffer) { if (WABAllocators.lpWABObject && WABAllocators.lpAllocateMore) { return(WABAllocators.lpAllocateMore(WABAllocators. lpWABObject, cbSize, lpObject, lppBuffer)); } else { return(MAPI_E_INVALID_OBJECT); } }
/******************************************************************************
Name : WABFreeBuffer
Purpose : Use the WAB Allocator
Parameters: lpBuffer = buffer to free
Returns : SCODE
Comment :
*******************************************************************************/ SCODE WABFreeBuffer(LPVOID lpBuffer) { if (WABAllocators.lpWABObject && WABAllocators.lpFreeBuffer) { return(WABAllocators.lpFreeBuffer(WABAllocators.lpWABObject, lpBuffer)); } else { return(MAPI_E_INVALID_OBJECT); } }
/***************************************************************************
Name : IsSpace
Purpose : Does the single or DBCS character represent a space?
Parameters: lpChar -> SBCS or DBCS character
Returns : TRUE if this character is a space
Comment :
***************************************************************************/ BOOL IsSpace(LPTSTR lpChar) { Assert(lpChar); if (*lpChar) { if (IsDBCSLeadByte(*lpChar)) { WORD CharType[2] = {0};
GetStringTypeA(LOCALE_USER_DEFAULT, CT_CTYPE1, lpChar, 2, // Double-Byte
CharType); return(CharType[0] & C1_SPACE); } else { return(*lpChar == ' '); } } else { return(FALSE); // end of string
} }
/******************************************************************************
Name : NetscapeImport
Purpose : Entry Point for NetScape Addressbook import
Parameters: hwnd = Handle to the parent Window lpAdrBook = pointer to the IADRBOOK interface lpWABObject = pointer to IWABOBJECT interface lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. lpOptions = pointer to WAB_IMPORT_OPTIONS structure
Returns :
Comment :
/******************************************************************************/ STDMETHODIMP NetscapeImport(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) { HRESULT hResult = S_OK;
SetGlobalBufferFunctions(lpWABObject);
hResult = MigrateUser(hwnd, lpOptions, lpProgressCB, lpAdrBook); if (hResult == hrMemory) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK); }
return(hResult); }
/******************************************************************************
Name : Athena16Import
Purpose : Entry Point for Athena 16 Addressbook import
Parameters: hwnd = Handle to the parent Window lpAdrBook = pointer to the IADRBOOK interface lpWABObject = poiinter to IWABOBJECT interface lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. lpOptions = pointer to WAB_IMPORT_OPTIONS structure
Returns :
Comment :
/******************************************************************************/ STDMETHODIMP Athena16Import(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) { HRESULT hResult = S_OK;
SetGlobalBufferFunctions(lpWABObject);
hResult = MigrateAthUser(hwnd, lpOptions, lpProgressCB,lpAdrBook);
return(hResult); }
/******************************************************************************
Name : EudoraImport
Purpose : Entry Point for Eudora Addressbook import
Parameters: hwnd = Handle to the parent Window lpAdrBook = pointer to the IADRBOOK interface lpWABObject = poiinter to IWABOBJECT interface lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. lpOptions = pointer to WAB_IMPORT_OPTIONS structure
Returns :
Comment :
/******************************************************************************/ STDMETHODIMP EudoraImport(HWND hwnd,LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) {
LPABCONT lpWabContainer = NULL; HRESULT hResult = S_OK;
SetGlobalBufferFunctions(lpWABObject);
if (FAILED(hResult = OpenWabContainer(&lpWabContainer, lpAdrBook))) { goto Error; }
hResult = MigrateEudoraUser(hwnd,lpWabContainer,lpOptions,lpProgressCB,lpAdrBook);
if (hResult == hrMemory) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK); }
if (lpWabContainer) { lpWabContainer->lpVtbl->Release(lpWabContainer); }
Error: return(hResult); }
STDMETHODIMP NetscapeExport(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) { SCODE sc = SUCCESS_SUCCESS; HRESULT hResult = hrSuccess;
SetGlobalBufferFunctions(lpWABObject);
return(hResult); }
STDMETHODIMP Athena16Export(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) { SCODE sc = SUCCESS_SUCCESS; HRESULT hResult = hrSuccess;
SetGlobalBufferFunctions(lpWABObject);
return(hResult); }
STDMETHODIMP EudoraExport(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions) { SCODE sc = SUCCESS_SUCCESS; HRESULT hResult = hrSuccess;
SetGlobalBufferFunctions(lpWABObject);
return(hResult); }
/******************************************************************************
*********************NetScape Functions*************************************** ****************************************************************************** * FUNCTION NAME:MigrateUser * * PURPOSE: Get the installation path of the address book and starts processing * the NetScape address book * * PARAMETERS: hwnd = Handle to the parent Window * lpAdrBook = pointer to the IADRBOOK interface * lpWABObject = poiinter to IWABOBJECT interface * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * * RETURNS: HRESULT ******************************************************************************/ HRESULT MigrateUser(HWND hwnd, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) { TCHAR szFileName[MAX_FILE_NAME]; HRESULT hResult; HANDLE h1 = NULL; WIN32_FIND_DATA lpFindFileData;
if (0 != (hResult= GetRegistryPath(szFileName, ARRAYSIZE(szFileName), NETSCAPE))) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_STRING_SELECTPATH), ARRAYSIZE(szGlobalTempAlloc)); if (IDNO ==MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_YESNO)) { return(ResultFromScode(MAPI_E_USER_CANCEL)); }
if (FALSE ==GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), NETSCAPE)) { return(ResultFromScode(MAPI_E_USER_CANCEL)); } } else { StrCatBuff(szFileName, LoadStringToGlobalBuffer(IDS_NETSCAPE_ADDRESSBOOK), ARRAYSIZE(szFileName)); h1 =FindFirstFile(szFileName,&lpFindFileData); if (h1 == INVALID_HANDLE_VALUE) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ADDRESS_HTM), ARRAYSIZE(szGlobalTempAlloc)); if (IDNO==MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_YESNO)) { h1=NULL; return(ResultFromScode(MAPI_E_USER_CANCEL));
} if (FALSE ==GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), NETSCAPE)) { h1=NULL; return(ResultFromScode(MAPI_E_USER_CANCEL)); } } FindClose(h1); }
hResult = ParseAddressBook(hwnd,szFileName,lpOptions,lpProgressCB,lpAdrBook); return(hResult); }
/******************************************************************************
* FUNCTION NAME:ParseAddressBook * * PURPOSE: Open the address book file ,put the data in a buffer and call * the ParseAddress function to do the parsing * * PARAMETERS: hwnd = Handle to the parent Window * lpAdrBook = pointer to the IADRBOOK interface * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * szFileName = Filename of the address book * * RETURNS: HRESULT ******************************************************************************/ HRESULT ParseAddressBook(HWND hwnd, LPTSTR szFileName, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) { ULONG ulRead = 0; HANDLE hFile = NULL; ULONG ulFileSize = 0; LPTSTR szBuffer = NULL; HRESULT hResult;
hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == hFile) { return(ResultFromScode(MAPI_E_NOT_FOUND)); }
ulFileSize = GetFileSize(hFile,NULL);
szBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulFileSize+1));
if (!szBuffer) { hResult = hrMemory; goto Error; }
if (! ReadFile(hFile, szBuffer, ulFileSize, &ulRead, NULL)) { goto Error; }
hResult = ParseAddress(hwnd,szBuffer,lpOptions,lpProgressCB,lpAdrBook);
Error: if (szBuffer) { LocalFree((HLOCAL)szBuffer); } if (hFile) { CloseHandle(hFile); }
return(hResult); }
/******************************************************************************
* FUNCTION NAME:ParseAddress * * PURPOSE: Gets the address portion of the address book in a buffer and calls * ProcessAdrBuffer for further processing * * PARAMETERS: hwnd = Handle to the parent Window * lpAdrBook = pointer to the IADRBOOK interface * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * szBuffer = Address book in a buffer * * RETURNS: HRESULT ******************************************************************************/
HRESULT ParseAddress(HWND hwnd, LPTSTR szBuffer, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) { LPTSTR AdrBuffer = NULL; //address starting <DL> to ending </DL>
HRESULT hResult = S_OK;
hResult = GetAdrBuffer(&szBuffer, &AdrBuffer); if (hrMemory == hResult) goto Error; if (hrINVALIDFILE == hResult) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_INVALID_FILE), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd,szGlobalTempAlloc,LoadStringToGlobalBuffer(IDS_ERROR), MB_OK); hResult = ResultFromScode(MAPI_E_CALL_FAILED); goto Error; }
hResult = ProcessAdrBuffer(hwnd,AdrBuffer,lpOptions,lpProgressCB,lpAdrBook);
Error: if (AdrBuffer) LocalFree((HLOCAL)AdrBuffer); return(hResult); }
/******************************************************************************
* FUNCTION NAME: GetAdrBuffer * * PURPOSE: Gets the address portion of the address book in a buffer * * PARAMETERS: szBuffer = points to the complete address book * szAdrBuffer = output buffer which gets filled up * * RETURNS: HRESULT ******************************************************************************/ HRESULT GetAdrBuffer(LPTSTR *szBuffer, LPTSTR *szAdrBuffer) { LPTSTR szAdrStart = NULL, szAdrBufStart = NULL, szAdrBufEnd = NULL; ULONG ulSize = 0;
// Get Adr Start
szAdrBufStart = GetAdrStart((*szBuffer));
szAdrBufEnd = GetAdrEnd((*szBuffer));
if (NULL == szAdrBufStart || NULL == szAdrBufEnd) { return(hrINVALIDFILE); }
if (szAdrBufEnd - szAdrBufStart) { ulSize = (ULONG) (szAdrBufEnd - szAdrBufStart); }
if (ulSize) {
*szAdrBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize+1));
if (!*szAdrBuffer) { return(hrMemory); } StrCpyN(*szAdrBuffer, szAdrBufStart, ulSize+1); *szBuffer= szAdrBufEnd; }
return(S_OK);
}
/******************************************************************************
* FUNCTION NAME:ProcessAdrBuffer * * PURPOSE: Gets the individual address and then fills up the WAB by calling appropriate functions. * * PARAMETERS: hwnd = Handle to the parent Window * lpAdrBook = pointer to the IADRBOOK interface * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * AdrBuffer = all the addresses in a buffer * * RETURNS: HRESULT ******************************************************************************/ HRESULT ProcessAdrBuffer(HWND hwnd, LPTSTR AdrBuffer, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) { LPTSTR szL = NULL, szDesc = NULL, szLine = NULL, szDescription = NULL; ULONG ulCount = 0; NSADRBOOK nsAdrBook; ULONG cCurrent = 0; LPSBinary lpsbinary = NULL; LPABCONT lpWabContainer = NULL; ULONG cProps; HRESULT hResult = S_OK; static LPSPropValue sProp = NULL; WAB_PROGRESS Progress; ULONG ul = 0;
ul = GetAddressCount(AdrBuffer); if (0 == ul) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_NO_ENTRY), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd,szGlobalTempAlloc,LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK); return(S_OK); }
ulCount=GetAddrCount((AdrBuffer));
if (ulCount) { lpsbinary = (LPSBinary)LocalAlloc(LMEM_FIXED,((ulCount+1)*sizeof(SBinary))); if (! lpsbinary) { return(hrMemory); } memset(lpsbinary,0,((ulCount+1) * sizeof(SBinary))); }
if (0 != (hResult = OpenWabContainer(&lpWabContainer, lpAdrBook))) { return(hResult); } if (0 != (hResult = lpWabContainer->lpVtbl->GetProps(lpWabContainer, (LPSPropTagArray)&ptaCon, 0, &cProps, (LPSPropValue *)&sProp))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(sProp); sProp = NULL; } goto Error; } Progress.denominator = ul; Progress.numerator = 0; Progress.lpText = NULL; ul = 0; while (GetAdrLine(&AdrBuffer, &szL, &szDesc)) { szLine = szL; szDescription = szDesc;
Progress.numerator = ul++; lpProgressCB(hwnd,&Progress);
if (0 == (hResult = ProcessLn(&szLine, &szDescription,&nsAdrBook,&AdrBuffer))) { if (nsAdrBook.DistList) { hResult=FillDistList(hwnd, lpWabContainer,sProp,lpOptions,&nsAdrBook, lpsbinary,lpAdrBook); } else { hResult = FillMailUser(hwnd, lpWabContainer,sProp, lpOptions,(void *)&nsAdrBook, lpsbinary,0,NETSCAPE); } }
if (szL) { LocalFree((HLOCAL)szL); szL = NULL; } if (szDesc) { LocalFree(szDesc); szDesc = NULL; } if (nsAdrBook.Description) { LocalFree((HLOCAL)nsAdrBook.Description); } nsAdrBook.Description = NULL; if (nsAdrBook.NickName) { LocalFree((HLOCAL)nsAdrBook.NickName); } nsAdrBook.NickName = NULL; if (nsAdrBook.Address) { LocalFree((HLOCAL)nsAdrBook.Address); } nsAdrBook.Address = NULL; if (nsAdrBook.Entry) { LocalFree((HLOCAL)nsAdrBook.Entry); } nsAdrBook.Entry = NULL; if (hrMemory == hResult) { break; }
}
if (sProp) { WABFreeBuffer(sProp); sProp = NULL; }
Error: if (NULL != lpsbinary) { for (ul=0; ul < ulCount + 1; ul++) { if (lpsbinary[ul].lpb) { LocalFree((HLOCAL)lpsbinary[ul].lpb); lpsbinary[ul].lpb=NULL; } }
LocalFree((HLOCAL)lpsbinary); lpsbinary = NULL; } if (lpWabContainer) { lpWabContainer->lpVtbl->Release(lpWabContainer); lpWabContainer = NULL; } return(S_OK); }
/******************************************************************************
* FUNCTION NAME:GetAdrLine * * PURPOSE: To get an address line and description of the address in a buffer * from NetScape address book. * * PARAMETERS: szCurPointer = pointer to the buffer containing the entire * addresses. * szBuffer = pointer to the address line buffer * szDesc = pointer to the description buffeer. * * RETURNS: BOOL ******************************************************************************/ BOOL GetAdrLine(LPTSTR *szCurPointer, LPTSTR *szBuffer, LPTSTR *szDesc) { static TCHAR szAdrStart[] = "<DT>"; static TCHAR szAdrEnd[] = "</A>"; static TCHAR szDescStart[] = "<DD>"; static TCHAR szDistListEnd[] = "</H3>"; LPTSTR temp = NULL; BOOL flag = TRUE;
ULONG ulSize = 0; LPTSTR szS = NULL, szE = NULL, szD = NULL, szDE = NULL ,szH = NULL;
szS = strstr(*szCurPointer, szAdrStart); szE = strstr(*szCurPointer, szAdrEnd); szH = strstr(*szCurPointer, szDistListEnd);
if (szS) { szS += lstrlen(szAdrStart); } else { return(FALSE); }
if (szE != NULL) { if (szH != NULL && szE <szH) { ulSize = (ULONG) (szE - szS + 1); flag = TRUE; } else { if (szH != NULL) { ulSize = (ULONG) (szH - szS + 1); flag = FALSE; } else { ulSize = (ULONG) (szE - szS + 1); flag = TRUE; } } } else { if (szH != NULL) { ulSize = (ULONG) (szH - szS + 1); flag = FALSE; } }
if (ulSize) { *szBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize + 1)); if (! *szBuffer) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK); return(FALSE); }
StrCpyN(*szBuffer, szS,ulSize); }
szD = strstr(*szCurPointer, szDescStart);
// check if DT flag comes before DD. that means DD is not for this address
temp = strstr((szS + 4), "<DT>"); if ((temp != NULL && temp < szD) || (szD == NULL)) { *szDesc = NULL; if (flag) { *szCurPointer = szE + lstrlen(szAdrEnd); } else { *szCurPointer = szH + lstrlen(szDistListEnd); } return(TRUE); } temp = NULL;
// Description will be uptil next \r\n
if (szD) { szD += lstrlen(szDescStart); szDE = strstr(szD, LoadStringToGlobalBuffer(IDS_EOL));
if (szDE) { szDE -= 1; }
ulSize = (ULONG) (szDE - szD + 1); }
if (ulSize) { *szDesc = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize+1)); if (! *szDesc) { StrCpyN(szGlobalTempAlloc,LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK); return(FALSE); }
StrCpyN(*szDesc, szD, ulSize); *szCurPointer = szDE + 2; } else { *szDesc = NULL; *szCurPointer = szDE + 2; }
return(TRUE); }
/******************************************************************************
* FUNCTION NAME:ProcessLn * * PURPOSE: Process an address line and fill the NSADRBOOK structure. * * PARAMETERS: szL = pointer to the address line buffer * szDesc = pointer to the description buffer * nsAdrBook = pointer to the NSADRBOOK structure. * * RETURNS: HRESULT ******************************************************************************/ HRESULT ProcessLn(LPTSTR *szL, LPTSTR *szDesc, NSADRBOOK *nsAdrBook, LPTSTR *szBuffer) { LPTSTR szPrmStart = NULL, szPrmEnd = NULL; TCHAR cMailto[MAX_STRING_SIZE]; TCHAR cAliasId[MAX_STRING_SIZE]; TCHAR cNickname[MAX_STRING_SIZE]; BOOL flag = FALSE; //To check for distribution list
LPNSDISTLIST present=NULL, previous=NULL; TCHAR *tmpStr = NULL; ULONG ulSize = 0; LPTSTR szDistStart = NULL, szDistEnd = NULL, szDistBuffer = NULL, szName = NULL;
LPTSTR temp = NULL; BOOL NoNickName = FALSE; HRESULT hResult = S_OK;
StrCpyN(cMailto, LoadStringToGlobalBuffer(IDS_MAILTO), ARRAYSIZE(cMailto)); StrCpyN(cAliasId, LoadStringToGlobalBuffer(IDS_ALIAS_ID), ARRAYSIZE(cAliasId)); StrCpyN(cNickname, LoadStringToGlobalBuffer(IDS_NICKNAME), ARRAYSIZE(cNickname));
memset(nsAdrBook,0, sizeof(NSADRBOOK)); nsAdrBook->DistList = TRUE; /* Get Mailto entry */ szPrmStart = strstr(*szL, cMailto); if (! szPrmStart) { flag = TRUE; nsAdrBook->DistList = TRUE; szName = strchr(*szL,'>'); goto AliasID; }
nsAdrBook->DistList = FALSE; szPrmStart += lstrlen(cMailto);
// search for quotes
szPrmEnd = szPrmStart; if (! szPrmEnd) { goto AliasID; }
while (*szPrmEnd != 34) { szPrmEnd = szPrmEnd + 1; // What if there is no end quote
if (szPrmEnd > (*szL + lstrlen(*szL))) { goto Down; } } ulSize = (ULONG) (szPrmEnd - szPrmStart); if (ulSize) { nsAdrBook->Address = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulSize + 1)); if (!nsAdrBook->Address) { return(hrMemory); } StrCpyN(nsAdrBook->Address, szPrmStart, ulSize+1); }
*szL = szPrmEnd + 1;
/* Get the AliasID */ if (szPrmEnd) { szName = strchr(szPrmEnd, '>'); } AliasID: szPrmStart = strstr(*szL, cAliasId); if (!szPrmStart) { nsAdrBook->Sbinary=FALSE; goto Nickname; } nsAdrBook->Sbinary=TRUE; szPrmStart += lstrlen(cAliasId); szPrmEnd = szPrmStart;
while (*szPrmEnd != 34) { szPrmEnd++;
if (szPrmEnd > (*szL + strlen(*szL))) { goto Down; } } ulSize = (ULONG) (szPrmEnd - szPrmStart + 1); tmpStr = (TCHAR *)LocalAlloc(LMEM_FIXED,ulSize); if (!tmpStr) { return(hrMemory); } StrCpyN(tmpStr, szPrmStart, ulSize);
nsAdrBook->AliasID = atoi(tmpStr); if (tmpStr) { LocalFree((HLOCAL)tmpStr); }
*szL = szPrmEnd + 1;
Nickname: szPrmStart = strstr(*szL, cNickname); if (!szPrmStart) { NoNickName = TRUE; goto Entry; } if (szName && szName < szPrmStart) { NoNickName = TRUE; goto Entry; } szPrmStart += lstrlen(cNickname); szPrmStart += 1; szPrmEnd = szPrmStart; while (*szPrmEnd != 34) { szPrmEnd++; if (szPrmEnd > (*szL + strlen(*szL))) { goto Down; } } ulSize = (ULONG) (szPrmEnd - szPrmStart); if (0 == ulSize) { NoNickName = TRUE; } else { NoNickName = FALSE; nsAdrBook->NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulSize + 1)); if (!nsAdrBook->NickName) { return(hrMemory); } StrCpyN(nsAdrBook->NickName, szPrmStart, ulSize + 1); }
*szL = szPrmEnd +1;
Entry: szPrmStart = szName; if (szPrmStart) { szPrmStart++; ulSize = (ULONG) ((*szL + lstrlen(*szL)) - szPrmStart); if (ulSize) { nsAdrBook->Entry = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulSize + 1)); if (!nsAdrBook->Entry) { return(hrMemory); } StrCpyN(nsAdrBook->Entry, szPrmStart, ulSize + 1); } if (/*NoNickName && */!nsAdrBook->Entry && nsAdrBook->Address) { ulSize = lstrlen(nsAdrBook->Address) + 1; nsAdrBook->Entry = (TCHAR *)LocalAlloc(LMEM_FIXED,ulSize); if (!nsAdrBook->Entry) { return(hrMemory); } StrCpyN(nsAdrBook->Entry, nsAdrBook->Address, ulSize); } }
if (*szDesc) { ulSize = lstrlen(*szDesc) + 1; nsAdrBook->Description = (TCHAR *)LocalAlloc(LMEM_FIXED, ulSize); if (! nsAdrBook->Description) { return(hrMemory); } StrCpyN(nsAdrBook->Description, *szDesc,ulSize); } else { nsAdrBook->Description = NULL; }
if (flag == TRUE) { ulSize = 0; szDistStart = GetAdrStart(*szBuffer); szDistEnd = GetDLNext(*szBuffer);
if (szDistEnd - szDistStart) { ulSize = (ULONG) (szDistEnd-szDistStart); } if (ulSize) { szDistBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize + 1)); if (!szDistBuffer) { return(hrMemory); } StrCpyN(szDistBuffer, szDistStart, ulSize + 1); *szBuffer=szDistEnd; } else { return(S_OK); } szPrmStart=szDistBuffer;
if ((temp = strstr(szPrmStart, LoadStringToGlobalBuffer(IDS_ALIASOF))) == NULL) { if (szDistBuffer) { LocalFree((HLOCAL)szDistBuffer); } return(S_OK); }
while ((szPrmEnd=strstr(szPrmStart, LoadStringToGlobalBuffer(IDS_ALIASOF)))!=NULL) {
present = (LPNSDISTLIST)LocalAlloc(LMEM_FIXED,sizeof(NSDISTLIST)); if (! present) { if (szDistBuffer) { LocalFree((HLOCAL)szDistBuffer); } return(hrMemory); } szPrmEnd += strlen(LoadStringToGlobalBuffer(IDS_ALIASOF)); szPrmStart = strchr(szPrmEnd,'"');
ulSize = (ULONG) (szPrmStart - szPrmEnd + 1); tmpStr = (TCHAR *)LocalAlloc(LMEM_FIXED,ulSize); if (! tmpStr) { return(hrMemory); } StrCpyN(tmpStr, szPrmEnd, ulSize);
present->AliasID = atoi(tmpStr); if (tmpStr) { LocalFree((HLOCAL)tmpStr); }
if (previous != NULL) { previous->lpDist = present; } else { nsAdrBook->lpDist = present; } previous=present;
} present->lpDist=NULL;
if (szDistBuffer) { LocalFree((HLOCAL)szDistBuffer); }
} else { nsAdrBook->lpDist=NULL; }
Down: return(S_OK); }
/******************************************************************************
* FUNCTION NAME:GetAddressCount * * PURPOSE: To get the count of number of <DT> in the buffer containing the * addresses. * * PARAMETERS: AdrBuffer = Buffer containing the addresses. * * RETURNS:ULONG , count of <DT> ******************************************************************************/ ULONG GetAddressCount(LPTSTR AdrBuffer) { TCHAR szToken[] = "<DT>"; LPTSTR szTemp = AdrBuffer; LPTSTR szP = NULL; ULONG ulCount = 0;
while ((szP = strstr(szTemp, szToken)) != NULL) { ulCount++; szTemp = szP + lstrlen(szToken); }
return(ulCount); }
/******************************************************************************
* FUNCTION NAME:GetAdrStart * * PURPOSE: To get a pointer to the starting of addresses in the NetScape * address book. * * PARAMETERS: szBuffer = pointer to the buffer containing the address book. * * RETURNS: LPTSTR, pointer to the starting of addresses (<DL><p>). ******************************************************************************/ LPTSTR GetAdrStart(LPTSTR szBuffer) { TCHAR szAdrStart[] = "<DL><p>"; LPTSTR szS=NULL;
szS = strstr(szBuffer, szAdrStart); if (szS) { szS += lstrlen(szAdrStart); }
return(szS); }
/******************************************************************************
* FUNCTION NAME:GetDLNext * * PURPOSE: To get a pointer to the </DL><p> in the address buffer. * * PARAMETERS: szBuffer = address buffer * * RETURNS: LPTSTR, pointer to the </DL><p> ******************************************************************************/ LPTSTR GetDLNext(LPTSTR szBuffer) { TCHAR szAdrStart[] = "</DL><p>"; LPTSTR szS = NULL;
szS = strstr(szBuffer, szAdrStart); if (szS) { szS += lstrlen(szAdrStart) + 1; } return(szS); }
/******************************************************************************
* FUNCTION NAME:GetAdrEnd * * PURPOSE: To get a pointer to the last occurance of </DL><p> in the address * buffer. * * PARAMETERS: szBuffer = address buffer * * RETURNS: LPTSTR, pointer to the last </DL><p> ******************************************************************************/ LPTSTR GetAdrEnd(LPTSTR szBuffer) { TCHAR szAdrEnd[] = "</DL><p>"; LPTSTR szE = NULL, szT = NULL; LPTSTR szTemp = szBuffer;
while ((szE = strstr(szTemp, szAdrEnd)) != NULL) { szT=szE; szTemp = szE + lstrlen(szAdrEnd); }
szE = szT;
if (szE) { szE += lstrlen(szAdrEnd); }
return(szE); }
/******************************************************************************
* FUNCTION NAME:GetAddrCount * * PURPOSE: To get a count of number of ALIASID in the address buffer. * * PARAMETERS: AdrBuffer = address buffer * * RETURNS: ULONG, count of total ALIASID in the address buffer ******************************************************************************/ ULONG GetAddrCount(LPTSTR AdrBuffer) { TCHAR szToken[MAX_STRING_SIZE]; LPTSTR szTemp=AdrBuffer; LPTSTR szP=NULL; ULONG ulCount=0;
StrCpyN(szToken, LoadStringToGlobalBuffer(IDS_ALIAS_ID), ARRAYSIZE(szToken));
while ((szP=strstr(szTemp,szToken))!=NULL) { ulCount++; szTemp =szP+lstrlen(szToken); }
return(ulCount); }
/******************************************************************************
* FUNCTION NAME:FillDistList * * PURPOSE: To create a Distribution list in the WAB. * * PARAMETERS: hwnd - hwnd of parent * lpWabContainer = pointer to the IABCONT interface * sProp = pointer to SPropValue * lpAdrBook = pointer to the IADRBOOK interface * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * lpsbinary = pointer to the SBinary array. * lpnAdrBook = pointer to the NSADRBOOK structure * * RETURNS: HRESULT ******************************************************************************/ HRESULT FillDistList(HWND hwnd, LPABCONT lpWabContainer, LPSPropValue sProp, LPWAB_IMPORT_OPTIONS lpOptions, LPNSADRBOOK lpnAdrBook, LPSBinary lpsbinary, LPADRBOOK lpAdrBook) {
LPNSDISTLIST lptemp=lpnAdrBook->lpDist; LPSPropValue lpNewDLProps = NULL; LPDISTLIST lpDistList = NULL; ULONG cProps; ULONG ulObjType; int i; HRESULT hResult; static LPMAPIPROP lpMailUserWAB =NULL; SPropValue rgProps[4]; LPMAPIPROP lpDlWAB = NULL; ULONG iCreateTemplatedl = iconPR_DEF_CREATE_DL;
BOOL flag = FALSE; REPLACE_INFO RI = {0}; ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT;
retry:
if (lpnAdrBook->Sbinary == FALSE) { if (0 != (hResult=CreateDistEntry(lpWabContainer,sProp,ulCreateFlags, &lpMailUserWAB))) { goto error1; } } else { if (lpsbinary[lpnAdrBook->AliasID].lpb == NULL) { if (0 != (hResult=CreateDistEntry(lpWabContainer,sProp,ulCreateFlags, &lpMailUserWAB))) { goto error1; } } else { if (0 != (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, lpsbinary[lpnAdrBook->AliasID].cb, (LPENTRYID)lpsbinary[lpnAdrBook->AliasID].lpb, (LPIID)&IID_IMAPIProp, MAPI_DEFERRED_ERRORS|MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpMailUserWAB))) { goto error1; } flag = TRUE; } }
if (lpnAdrBook->Entry) { rgProps[0].Value.lpszA = lpnAdrBook->Entry; rgProps[0].ulPropTag = PR_DISPLAY_NAME; } else if (lpnAdrBook->NickName) { rgProps[0].Value.lpszA = lpnAdrBook->NickName; rgProps[0].ulPropTag = PR_DISPLAY_NAME; } else { rgProps[0].Value.lpszA = NULL; rgProps[0].ulPropTag = PR_NULL; }
rgProps[1].Value.lpszA = lpnAdrBook->Description; if (lpnAdrBook->Description) { rgProps[1].ulPropTag = PR_COMMENT; } else { rgProps[1].ulPropTag = PR_NULL; }
if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 2, rgProps, NULL))) { goto error1; }
if (0 != (hResult=lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB, FORCE_SAVE|KEEP_OPEN_READWRITE))) { if (GetScode(hResult) == MAPI_E_COLLISION) { if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) { if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); } lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry; }
if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) { hResult = S_OK; goto error1; }
if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) { if (lpnAdrBook->Entry) { RI.lpszDisplayName = lpnAdrBook->Entry; RI.lpszEmailAddress = lpnAdrBook->Address; } else if (lpnAdrBook->NickName) { RI.lpszDisplayName = lpnAdrBook->NickName; RI.lpszEmailAddress = lpnAdrBook->Address; } else if (lpnAdrBook->Address) { RI.lpszDisplayName = lpnAdrBook->Address; RI.lpszEmailAddress = NULL; } else if (lpnAdrBook->Description) { RI.lpszDisplayName = lpnAdrBook->Description; RI.lpszEmailAddress = NULL; } else { RI.lpszDisplayName = ""; RI.lpszEmailAddress = NULL; } RI.ConfirmResult = CONFIRM_ERROR; RI.fExport = FALSE; RI.lpImportOptions = lpOptions;
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ImportReplace), hwnd, ReplaceDialogProc, (LPARAM)&RI);
switch (RI.ConfirmResult) { case CONFIRM_YES: case CONFIRM_YES_TO_ALL: lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry; break;
case CONFIRM_NO: if (lpnAdrBook->Sbinary == TRUE) { hResult = GetExistEntry(lpWabContainer,lpsbinary, lpnAdrBook->AliasID, lpnAdrBook->Entry, lpnAdrBook->NickName); } goto error1;
case CONFIRM_ABORT: hResult = ResultFromScode(MAPI_E_USER_CANCEL); goto error1;
default:
break; } } } }
if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB, (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; } goto error1; }
if (lpnAdrBook->Sbinary == TRUE) { if (flag == FALSE) { lpsbinary[lpnAdrBook->AliasID].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED, lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); if (! lpsbinary[lpnAdrBook->AliasID].lpb) { hResult = hrMemory; goto error1; } CopyMemory(lpsbinary[lpnAdrBook->AliasID].lpb, (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb, lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); lpsbinary[lpnAdrBook->AliasID].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb; } }
if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; }
if (0 != (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb, (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb, (LPIID)&IID_IDistList, MAPI_DEFERRED_ERRORS|MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpDistList))) { goto error1; }
if (lpNewDLProps) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; } if (NULL == lpnAdrBook->lpDist) { goto error1; } do { i = lpnAdrBook->lpDist->AliasID;
if ((LPENTRYID)lpsbinary[i].lpb == NULL) { if (0 != (hResult=CreateDistEntry(lpWabContainer,sProp,ulCreateFlags, &lpMailUserWAB))) { goto error2; }
rgProps[0].ulPropTag = PR_DISPLAY_NAME; rgProps[0].Value.lpszA = LoadStringToGlobalBuffer(IDS_DUMMY);
if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 1, rgProps, NULL))) { goto error2; } if (0 != (hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB, FORCE_SAVE|KEEP_OPEN_READONLY))) { goto error2; }
if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB, (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; } goto error2; }
lpsbinary[i].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); if (!lpsbinary[i].lpb) { hResult = hrMemory; goto error1; } CopyMemory(lpsbinary[i].lpb, (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); lpsbinary[i].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb;
if (lpNewDLProps) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; } error2:
if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; } }
if (0 != (hResult = lpDistList->lpVtbl->CreateEntry(lpDistList, lpsbinary[i].cb, (LPENTRYID)lpsbinary[i].lpb, CREATE_CHECK_DUP_STRICT|CREATE_REPLACE, &lpDlWAB))) { goto error3; }
if (0 != (hResult = lpDlWAB->lpVtbl->SaveChanges(lpDlWAB, FORCE_SAVE))) { if (MAPI_E_FOLDER_CYCLE ==hResult) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_LOOPING), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ENTRY_NOIMPORT),MB_OK); } hResult = S_OK; goto error3; } error3: if (lpDlWAB) { lpDlWAB->lpVtbl->Release(lpDlWAB); lpDlWAB = NULL; }
lpnAdrBook->lpDist = FreeNSdistlist(lpnAdrBook->lpDist); } while (lpnAdrBook->lpDist!=NULL);
error1:
if (lpDistList) { lpDistList->lpVtbl->Release(lpDistList); lpDistList = NULL; }
if (lpDlWAB) { lpDlWAB->lpVtbl->Release(lpDlWAB); lpDlWAB = NULL; }
if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; } return(hResult); }
/******************************************************************************
* FUNCTION NAME: FillWABStruct * * PURPOSE: To fill the SpropValue array. * * PARAMETERS: nsAdrBook = pointer to the NSADRBOOK structure. * rgProps = pointer to the SpropValue array. * * RETURNS: HRESULT ******************************************************************************/ HRESULT FillWABStruct(LPSPropValue rgProps, NSADRBOOK *nsAdrBook) { HRESULT hr = S_OK;
rgProps[1].ulPropTag = PR_DISPLAY_NAME; if (nsAdrBook->Entry) { rgProps[1].Value.lpszA = nsAdrBook->Entry; } else if (nsAdrBook->NickName) { rgProps[1].Value.lpszA = nsAdrBook->NickName; } else { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_NONAME), ARRAYSIZE(szGlobalTempAlloc)); rgProps[1].Value.lpszA = szGlobalTempAlloc; }
rgProps[0].Value.lpszA = nsAdrBook->Address; if (nsAdrBook->Address) { rgProps[0].ulPropTag = PR_EMAIL_ADDRESS; rgProps[2].ulPropTag = PR_ADDRTYPE; rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP); } else { rgProps[0].ulPropTag = PR_NULL; rgProps[2].ulPropTag = PR_NULL; rgProps[2].Value.lpszA = NULL; }
rgProps[3].Value.lpszA = nsAdrBook->Description; if (nsAdrBook->Description) { rgProps[3].ulPropTag = PR_COMMENT; } else { rgProps[3].ulPropTag = PR_NULL; }
rgProps[4].Value.lpszA = nsAdrBook->NickName; if (nsAdrBook->NickName) { rgProps[4].ulPropTag = PR_NICKNAME; } else { rgProps[4].ulPropTag = PR_NULL; }
return(hr); }
/******************************************************************************
* FUNCTION NAME:CreateDistEntry * * PURPOSE: To create an entry in the WAB for a Distribution List * * PARAMETERS: lpWabContainer = pointer to the WAB container. * sProp = pointer to SPropValue * ulCreateFlags = Flags * lppMailUserWab = pointer to the IMAPIPROP interface * * RETURNS: HRESULT ******************************************************************************/ HRESULT CreateDistEntry(LPABCONT lpWabContainer,LPSPropValue sProp, ULONG ulCreateFlags,LPMAPIPROP *lppMailUserWab) { HRESULT hResult; ULONG iCreateTemplatedl = iconPR_DEF_CREATE_DL;
hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer, sProp[iCreateTemplatedl].Value.bin.cb, (LPENTRYID)sProp[iCreateTemplatedl].Value.bin.lpb, ulCreateFlags, lppMailUserWab); return(hResult); }
/******************************************************************************
* FUNCTION NAME:FreeNSdistlist * * PURPOSE: To free one node from NSDISTLIST(linked list) * * PARAMETERS: lpDist = pointer to the NSDISTLIST structure. * * RETURNS: LPNSDISTLIST , pointer to the next link. ******************************************************************************/ LPNSDISTLIST FreeNSdistlist(LPNSDISTLIST lpDist) { LPNSDISTLIST lpTemp = NULL;
if (lpDist==NULL) { return(NULL); }
lpTemp = lpDist->lpDist; LocalFree((HLOCAL)lpDist); lpDist = NULL; return(lpTemp); }
/******************************************************************************
*********************Eudora Functions*****************************************/
HRESULT ImportEudoraAddressBookFile(HWND hwnd, LPTSTR szFileName, LPABCONT lpWabContainer, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) { HRESULT hResult = E_FAIL; ULONG cProps; LPEUDADRBOOK lpeudAdrBook = NULL; ULONG ulCount = 0, uCounter = 0; LPSPropValue sProp = NULL;
if (! (ulCount = ParseEudAddress(szFileName,&lpeudAdrBook))) { goto Error; }
if (0 != (hResult = lpWabContainer->lpVtbl->GetProps(lpWabContainer, (LPSPropTagArray)&ptaCon, 0, &cProps, (LPSPropValue *)&sProp))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(sProp); sProp = NULL; } goto Error; }
hResult = ImportEudUsers(hwnd, szFileName, lpWabContainer, sProp, lpeudAdrBook,ulCount, lpOptions,lpProgressCB,lpAdrBook); if (sProp) { WABFreeBuffer(sProp); } Error: if (lpeudAdrBook) {
for (; uCounter < ulCount ; uCounter++) { if (lpeudAdrBook[uCounter].Description) { LocalFree((HLOCAL)lpeudAdrBook[uCounter].Description); } lpeudAdrBook[uCounter].Description = NULL; if (lpeudAdrBook[uCounter].NickName) { LocalFree((HLOCAL)lpeudAdrBook[uCounter].NickName); } lpeudAdrBook[uCounter].NickName = NULL; if (lpeudAdrBook[uCounter].Address) { LocalFree((HLOCAL)lpeudAdrBook[uCounter].Address); } lpeudAdrBook[uCounter].Address = NULL; } LocalFree((HLOCAL)lpeudAdrBook); lpeudAdrBook=NULL; }
return(hResult); }
/******************************************************************************
* FUNCTION NAME:MigrateEudoraUser * * PURPOSE: Get the installation path of the address book and starts processing * the Eudora address book * * PARAMETERS: hwnd = Handle to the parent Window * lpAdrBook = pointer to the IADRBOOK interface * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * lpWabContainer = pointer to the IABCONT interface * * RETURNS: HRESULT ******************************************************************************/ HRESULT MigrateEudoraUser(HWND hwnd, LPABCONT lpWabContainer, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) {
TCHAR szFileName[MAX_FILE_NAME]; TCHAR szFilePath[MAX_FILE_NAME]; TCHAR szFileSubPath[MAX_FILE_NAME]; HRESULT hResult = S_OK; WIN32_FIND_DATA FindFileData; HANDLE hFile = NULL;
szFilePath[0] = szFileName[0] = '\0';
hResult= GetRegistryPath(szFileName, ARRAYSIZE(szFileName), EUDORA); if (hResult == hrMemory) { return(hrMemory); }
if (0 != hResult) { // Didnt find the registry setting .. look for "c:\eudora"
StrCpyN(szFileName, LoadStringToGlobalBuffer(IDS_EUDORA_DEFAULT_INSTALL), ARRAYSIZE(szFileName));
if (0xFFFFFFFF != GetFileAttributes(szFileName)) { // This directory exists .. reset the error value
hResult = S_OK; } }
if (0 != hResult) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_STRING_SELECTPATH), ARRAYSIZE(szGlobalTempAlloc)); if (IDNO ==MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE), MB_YESNO)) { return(ResultFromScode(MAPI_E_USER_CANCEL)); } if (!GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), EUDORA)) { return(ResultFromScode(MAPI_E_USER_CANCEL)); } } else { StrCatBuff(szFileName, LoadStringToGlobalBuffer(IDS_EUDORA_ADDRESS), ARRAYSIZE(szFileName)); hFile = FindFirstFile(szFileName,&FindFileData); if (INVALID_HANDLE_VALUE == hFile) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ADDRESS_HTM), ARRAYSIZE(szGlobalTempAlloc)); if (IDNO == MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_YESNO)) { return(ResultFromScode(MAPI_E_USER_CANCEL)); } if (FALSE ==GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), EUDORA)) { return(ResultFromScode(MAPI_E_USER_CANCEL)); }
} else { FindClose(hFile); } }
// Extract the file directory from the file name
if (lstrlen(szFileName) && !lstrlen(szFilePath)) { LPTSTR lp1 = NULL, lp2 = NULL; StrCpyN(szFilePath,szFileName, ARRAYSIZE(szFilePath)); lp1 = szFilePath; // Find the last '\' and terminate the path at that char
while (lp1 && *lp1) { if (*lp1 == '\\') { lp2 = lp1; } lp1 = CharNext(lp1); } if (lp2 && (*lp2 == '\\')) { *lp2 = '\0'; } }
// import the basic file ...
//
hResult = ImportEudoraAddressBookFile(hwnd, szFileName, lpWabContainer, lpOptions, lpProgressCB, lpAdrBook);
szFileName[0]='\0';
// Now look for files in the nicknames subdirectory
//
StrCatBuff(szFilePath, LoadStringToGlobalBuffer(IDS_EUDORA_SUBDIR_NAME), ARRAYSIZE(szFilePath));
if (0xFFFFFFFF != GetFileAttributes(szFilePath)) { BOOL bRet = TRUE;
// Yes this directory exists ...
// Now scan all the *.txt files in this subdir and try to import them
StrCpyN(szFileSubPath, szFilePath, ARRAYSIZE(szFileSubPath)); StrCatBuff(szFileSubPath, LoadStringToGlobalBuffer(IDS_EUDORA_GENERIC_SUFFIX), ARRAYSIZE(szFileSubPath));
hFile = FindFirstFile(szFileSubPath, &FindFileData);
while (bRet && hFile != INVALID_HANDLE_VALUE) { StrCpyN(szFileName, szFilePath, ARRAYSIZE(szFileName)); StrCatBuff(szFileName, TEXT("\\"), ARRAYSIZE(szFileName)); StrCatBuff(szFileName, FindFileData.cFileName, ARRAYSIZE(szFileName)); hResult = ImportEudoraAddressBookFile(hwnd, szFileName, lpWabContainer, lpOptions, lpProgressCB, lpAdrBook); hResult = S_OK;
// Dont report errors .. just continue ...
bRet = FindNextFile(hFile, &FindFileData); }
if (hFile) { FindClose(hFile); } }
return(hResult); }
/******************************************************************************
* FUNCTION NAME:ParseEudAddress * * PURPOSE: To open the nndbase.txt and toc files and starts processing the * address book. * * PARAMETERS: szFileName = contains the path of the address book. * lppeudAdrBook = pointer to the EUDADRBOOK structure. * * RETURNS: ULONG, number of addresses in the address book. ******************************************************************************/ ULONG ParseEudAddress(LPTSTR szFileName, LPEUDADRBOOK *lppeudAdrBook) { HANDLE htoc,htxt; TCHAR cNndbasetoc[_MAX_PATH]; ULONG ucount=0; ULONG ulAdrcount=0; UINT i,j; LPTSTR szBuffer=NULL; LPTSTR szAdrBuffer=NULL; LPTSTR *szAliaspt=NULL; ULONG ulRead=0; ULONG ulFileSize,ulTxtSize; LPEUDADRBOOK lpeudAdrBook;
StrCpyN(cNndbasetoc,szFileName, ARRAYSIZE(cNndbasetoc)); cNndbasetoc[strlen(cNndbasetoc)-3] = '\0'; StrCatBuff(cNndbasetoc, LoadStringToGlobalBuffer(IDS_EUDORA_TOC), ARRAYSIZE(cNndbasetoc));
/* Eudora address book has two files,nndbase.txt and nndbase.toc.
nndbase.toc format: Nicknames start from byte 3. Every Nickname will be delimited by /r/n. After this there will 4 byte address offset,4 byte address size, 4 byte description offset and 4 byte description size. The address offset and size constitute all the addresses in the NickName.(A NickName can be a distribution list or a single mail user */
htoc = CreateFile(cNndbasetoc, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == htoc) { goto Error; }
htxt = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == htxt) { goto Error; }
//get toc file in a buffer
ulFileSize = GetFileSize(htoc, NULL); szBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulFileSize+1));
if (! szBuffer) { goto NoMemory; } if (! ReadFile(htoc, szBuffer, ulFileSize, &ulRead, NULL)) { goto Error; }
szBuffer[ulFileSize] = '\0';
//get address file in a buffer
ulTxtSize = GetFileSize(htxt, NULL);
szAdrBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulTxtSize+1));
if (!szAdrBuffer) { goto NoMemory; }
if (! ReadFile(htxt, szAdrBuffer, ulTxtSize, &ulRead, NULL)) { goto Error; } szAdrBuffer[ulTxtSize] = '\0'; // BUG 2120: to deal with only LF's and not CR/LF's
for (i = 2; i < (UINT)ulFileSize; i++) { if (! (/*szBuffer[i] == '\r' && */szBuffer[i+1] == '\n') ) { continue; } ulAdrcount++ ; //to get count of number of address
}
if (ulAdrcount) { lpeudAdrBook = (LPEUDADRBOOK)LocalAlloc(LMEM_FIXED, ((ulAdrcount) * sizeof(EUDADRBOOK))); if (!lpeudAdrBook) { goto NoMemory; }
memset(lpeudAdrBook,0,((ulAdrcount) * sizeof(EUDADRBOOK)));
szAliaspt = (LPTSTR *)LocalAlloc(LMEM_FIXED,(sizeof(LPTSTR))*(ulAdrcount+1)); if (! szAliaspt) { goto NoMemory; }
for (i = 0; i < ulAdrcount; i++) { szAliaspt[i] = (LPTSTR)LocalAlloc(LMEM_FIXED,256); if (!szAliaspt[i]) { goto NoMemory; } }
szAliaspt[i]=NULL; //to know it is the end.
j=0;
for (i = 2; i < (UINT)ulFileSize; i++) { // BUG 2120: to deal with only LF's and not CR/LF's
if ((/*szBuffer[i] == '\r' &&*/ szBuffer[i+1] == '\n')) { i += (EUDORA_STRUCT + 1); //16 bytes structure +1 for 10
szAliaspt[ucount][j] = '\0'; ucount++; j=0; continue; } szAliaspt[ucount][j++]=szBuffer[i]; }
if (hrMemory == ParseAddressTokens(szBuffer,szAdrBuffer,ulAdrcount,szAliaspt,lpeudAdrBook)) { goto NoMemory; } *lppeudAdrBook = lpeudAdrBook; }
Error: if (szBuffer) { LocalFree((HLOCAL)szBuffer); } if (szAdrBuffer) { LocalFree((HLOCAL)szAdrBuffer); } if (htxt) { CloseHandle(htxt); } if (htoc) { CloseHandle(htoc); } if (szAliaspt) { for (i = 0; i < ulAdrcount; i++) { if (szAliaspt[i]) { LocalFree((HLOCAL)szAliaspt[i]); } szAliaspt[i] = NULL; } LocalFree((HLOCAL)szAliaspt); szAliaspt = NULL; }
return(ulAdrcount);
NoMemory: StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK); if (szBuffer) { LocalFree((HLOCAL)szBuffer); } if (szAdrBuffer) { LocalFree((HLOCAL)szAdrBuffer); } if (htxt) { CloseHandle(htxt); } if (htoc) { CloseHandle(htoc); } if (szAliaspt) { for (i = 0; i < ulAdrcount; i++) { if (szAliaspt[i]) { LocalFree((HLOCAL)szAliaspt[i]); } szAliaspt[i] = NULL; } LocalFree((HLOCAL)szAliaspt); szAliaspt = NULL; } return(0); }
/******************************************************************************
* FUNCTION NAME:ParseAddressTokens * * PURPOSE: To fill the EUDADRBOOK array structure after processing all the * addresses from Eudora address book. * * PARAMETERS: szBuffer = buffer containing the nndbase.toc file. * szAdrBuffer = buffer containing the nndbase.txt file. * ulCount = number of addresses in the eudora address book. * szAliaspt = pointer to a two dimensional array containing * all the nicknames. * EudAdrBook = pointer to the EUDADRBOOK structure. * * RETURNS: HRESULT ******************************************************************************/ HRESULT ParseAddressTokens(LPTSTR szBuffer,LPTSTR szAdrBuffer,UINT ulCount, LPTSTR *szAliaspt,EUDADRBOOK *EudAdrBook) {
ULONG ulAdrSize = 0, ulAdrOffset = 0, i = 0, uDescription = 0, uOffset = 0; int iCounter =0; LPTSTR szAdrLine = NULL, szAdrEnd = NULL, szAdrStart=NULL, szAdrCur=NULL;
HRESULT hr = S_OK;
szAdrStart=&szBuffer[2];
do { if (szAliaspt[i] == NULL) { break; } szAdrCur = Getstr(szAdrStart, szAliaspt[i]); if (szAdrCur == NULL) { hr = hrMemory; goto Error; } szAdrCur+=strlen(szAliaspt[i])+2; ulAdrOffset = ShiftAdd(0,szAdrCur); ulAdrSize = ShiftAdd(4,szAdrCur);
szAdrStart=szAdrCur+16; EudAdrBook[i].lpDist=NULL; if (hrMemory == (hr = CreateAdrLineBuffer(&szAdrLine,szAdrBuffer,ulAdrOffset,ulAdrSize))) { goto Error; } if (hrMemory == (hr = ParseAdrLineBuffer(szAdrLine,szAliaspt,i,EudAdrBook))) { goto Error; } ulAdrOffset = ShiftAdd(8,szAdrCur); ulAdrSize = ShiftAdd(12,szAdrCur);
if (! (ulAdrSize == 0xFFFFFFFF && ulAdrOffset == 0xFFFFFFFF)) { EudAdrBook[i].Description = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulAdrSize+1)); if (! EudAdrBook[i].Description) { hr = hrMemory; goto Error; } for (uDescription = 0, uOffset = 0; uDescription < ulAdrSize; uDescription++,uOffset++) { if (szAdrBuffer[ulAdrOffset + uOffset] != 03) { //delimitor for next line in nndbase.txt file
EudAdrBook[i].Description[uDescription] = szAdrBuffer[ulAdrOffset + uOffset]; } else { EudAdrBook[i].Description[uDescription++] = '\r'; EudAdrBook[i].Description[uDescription] = '\n'; } } // Bug 29803 - this line is not being terminated - has garrbage at end ...
EudAdrBook[i].Description[uDescription] = '\0'; } else { EudAdrBook[i].Description = NULL; }
i++; if (szAdrLine) { LocalFree((HLOCAL)szAdrLine); } szAdrLine = NULL;
} while (szAdrStart[0]!='\0');
Error: if (szAdrLine) { LocalFree((HLOCAL)szAdrLine); } szAdrLine = NULL;
return(hr); }
/*******************************************************************************
* FUNCTION NAME:CreateAdrLineBuffer * * PURPOSE: To get an address line in a buufer from the buffer conatining * the addressbook. * * PARAMETERS: szAdrline = pointer to the address line buffer. * szAdrBuffer = pointer to the buffer containing the address book. * ulAdrOffset = offset of the address line in the szAdrBuffer * ulAdrSize = size of the address line in the szAdrBuffer * * RETURNS: HRESULT ******************************************************************************/ HRESULT CreateAdrLineBuffer(LPTSTR *szAdrline, LPTSTR szAdrBuffer, ULONG ulAdrOffset, ULONG ulAdrSize) { LPTSTR Temp = NULL; ULONG ucount; Temp = &szAdrBuffer[ulAdrOffset];
*szAdrline = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulAdrSize + 2));
if (! (*szAdrline)) { return(hrMemory); } // BUG 2120: to deal with only LF's and not CR/LF's
for (ucount = 0; ucount < ulAdrSize + 2; ucount++) { // want to stop when get to LF and will check later if
// it was preceded by a CR
if (/*Temp[ucount] == '\r' && */Temp[ucount/*+1*/] == '\n') { break; } (*szAdrline)[ucount] = Temp[ucount]; } // if there was a CR before the LF remove it
if( (*szAdrline)[ucount-1] == '\r' ) (*szAdrline)[ucount-1] = '\0'; (*szAdrline)[ucount] = '\0';
return(S_OK); }
/******************************************************************************
* FUNCTION NAME:ParseAdrLineBuffer * * PURPOSE: To parse each address line and fill the EUDADRBOOK structure. * * PARAMETERS: szAdrLine = pointer to the buffer containing an address line. * szAliaspt = pointer to a two dimensional array containing * all the nicknames. * uToken = position of this address in the address book. * EudAdrBook = pointer to the EUDADRBOOK structure. * * RETURNS: HRESULT ******************************************************************************/ HRESULT ParseAdrLineBuffer(LPTSTR szAdrLine,LPTSTR *szAliasptr,ULONG uToken, EUDADRBOOK *EudAdrBook) { LPTSTR szAdrEnd = NULL, szAdrStart = NULL, szAdrDummy = NULL; LPTSTR szAdrCur = NULL; INT uCount = 0; LPEUDDISTLIST present = NULL, previous = NULL; BOOL flag = TRUE; UINT Parse = 0; HRESULT hResult = S_OK; szAdrStart = szAdrLine;
// Bug 44576 - this code below is assuming that a ',' in a string implies a group
// However, there can be "...text, text..." as one item in the input in which case
// this code really barfs ...
// The code also assumes that <spaces> are delimiters which also wont work with
// the strings as above ..
//
// Try changing ',' inside quoted strings to ';' so this code wont trip on them
// Looks like this code is also throwing away the info in quotes if the string is of
// the form alias XXX "YYY" zz@zz .. the part in ".." is discarded ??? Fix that as a
// seperate bug ...
{ LPTSTR lp = szAdrStart; BOOL bWithinQuotes = FALSE; while(lp && *lp) { if(*lp == '"') bWithinQuotes = !bWithinQuotes; if(*lp == ',' && bWithinQuotes) *lp = ';'; lp = CharNext(lp); } }
//To check whether it is a dl or a simple address??
if ((szAdrDummy=strstr(szAdrStart,","))==NULL) { flag=FALSE; } else { if ('\0'==szAdrDummy[1]) { flag=FALSE; } }
szAdrCur=strtok(szAdrStart,", "); if (NULL == szAdrCur) { EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1); if (! EudAdrBook[uToken].NickName) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].NickName,szAliasptr[uToken],lstrlen(szAliasptr[uToken])+1); EudAdrBook[uToken].lpDist=NULL; EudAdrBook[uToken].Address = NULL; return(S_OK); } while (szAdrCur!=NULL) { if (SearchAdrName(szAdrCur)) { if (flag) { present = (LPEUDDISTLIST)LocalAlloc(LMEM_FIXED, sizeof(EUDDISTLIST)); if (! present) { return(hrMemory); } memset(present,0,sizeof(EUDDISTLIST)); if (previous == NULL) { EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1); if (! EudAdrBook[uToken].NickName) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].NickName,szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1); EudAdrBook[uToken].Address = NULL; } present->AliasID=uCount; present->flag=TRUE; present->Address = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAdrCur)+1); if (! present->Address) { hResult = hrMemory; goto Error; } StrCpyN(present->Address,szAdrCur, lstrlen(szAdrCur)+1);
present->NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAdrCur)+1); if (! present->NickName) { hResult = hrMemory; goto Error; } StrCpyN(present->NickName,szAdrCur, lstrlen(szAdrCur)+1); if (previous!=NULL) { previous->lpDist=present; } else { EudAdrBook[uToken].lpDist = present; } previous=present; } else { EudAdrBook[uToken].Address = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAdrCur)+1); if (! EudAdrBook[uToken].Address) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].Address,szAdrCur, lstrlen(szAdrCur)+1); EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1); if (! EudAdrBook[uToken].NickName) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].NickName,szAliasptr[uToken], strlen(szAliasptr[uToken])+1); EudAdrBook[uToken].lpDist=NULL; }
} else { if ((uCount=SearchName(szAliasptr,szAdrCur))>=0) { if (flag) { present = (LPEUDDISTLIST)LocalAlloc(LMEM_FIXED, sizeof(EUDDISTLIST)); if (! present) { return(hrMemory); } memset(present,0,sizeof(EUDDISTLIST));
if (previous == NULL) { EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1); if (!EudAdrBook[uToken].NickName) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].NickName, szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1); EudAdrBook[uToken].Address = NULL; } present->AliasID=uCount; present->flag=FALSE; if (previous!=NULL) { previous->lpDist=present; } else { EudAdrBook[uToken].lpDist = present; } previous=present; } else { EudAdrBook[uToken].lpDist = (LPEUDDISTLIST)LocalAlloc(LMEM_FIXED, sizeof(EUDDISTLIST)); if (! EudAdrBook[uToken].lpDist) { return(hrMemory); } //memset(present,0,sizeof(EUDDISTLIST));
EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1); if (! EudAdrBook[uToken].NickName) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].NickName, szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1); EudAdrBook[uToken].Address = NULL; EudAdrBook[uToken].lpDist->AliasID=uCount; EudAdrBook[uToken].lpDist->flag=FALSE; EudAdrBook[uToken].lpDist->lpDist=NULL; } } else { //not a valid email address or a valid nickname
if (FALSE==flag) { if (! EudAdrBook[uToken].Address && SearchAdrName(szAdrCur)) { EudAdrBook[uToken].Address = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAdrCur)+1); if (! EudAdrBook[uToken].Address) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].Address, szAdrCur, lstrlen(szAdrCur)+1); } if (! EudAdrBook[uToken].NickName) { EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1); if (! EudAdrBook[uToken].NickName) { hResult = hrMemory; goto Error; } StrCpyN(EudAdrBook[uToken].NickName, szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1); } EudAdrBook[uToken].lpDist=NULL; } }
} szAdrCur=strtok(NULL,", "); }
if (present!=NULL) { present->lpDist=NULL; } return(hResult);
Error: while (EudAdrBook[uToken].lpDist != NULL) { EudAdrBook[uToken].lpDist = FreeEuddistlist(EudAdrBook[uToken].lpDist); } return(hResult);
}
/******************************************************************************
* FUNCTION NAME:SearchAdrName * * PURPOSE: To search if the token is an address or a name(whether it contains * a @ or not). * * PARAMETERS: szAdrCur = pointer to the token. * * RETURNS: BOOL, TRUE if it contains @ ******************************************************************************/ BOOL SearchAdrName(LPTSTR szAdrCur) { if (strchr(szAdrCur, '@') == NULL) { return(FALSE); }
return(TRUE); }
/******************************************************************************
* FUNCTION NAME:SearchName * * PURPOSE: To search for the token in the szAliasptr which conatins all * the nick names. * * PARAMETERS: szAdrCur = pointer to the token to be searched. * szAliaspt = pointer to a two dimensional array containing * all the nicknames. * * RETURNS: INT, position of the token in the szAliaspt ******************************************************************************/ INT SearchName(LPTSTR *szAliasptr, LPTSTR szAdrCur) { INT uCount=0;
while (szAliasptr[uCount]!=NULL) { if (lstrcmpi(szAliasptr[uCount],szAdrCur) == 0) { return(uCount); } uCount++; } return(-1); }
/******************************************************************************
* FUNCTION NAME:ImportEudUsers * * PURPOSE: * * PARAMETERS: hwnd = Handle to the parent Window * lpAdrBook = pointer to the IADRBOOK interface * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * lpWabContainer = pointer to the IABCONT interface * lpeudAdrBook = pointer to the EUDADRBOOK structure * ulCount = counter value which holds the position of this address * in the Eudora address book. * sProp = pointer to SPropValue * * RETURNS: hresult ******************************************************************************/ HRESULT ImportEudUsers(HWND hwnd, LPTSTR szFileName, LPABCONT lpWabContainer, LPSPropValue sProp, LPEUDADRBOOK lpeudAdrBook, ULONG ulCount, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) {
HRESULT hResult = S_OK; ULONG ul; LPSBinary lpsbinary; WAB_PROGRESS Progress;
lpsbinary = (LPSBinary)LocalAlloc(LMEM_FIXED, ((ulCount+1) * sizeof(SBinary))); if (! lpsbinary) { hResult = hrMemory; goto Error; } memset(lpsbinary, 0, ((ulCount + 1) * sizeof(SBinary)));
Progress.denominator = ulCount; Progress.numerator = 0; Progress.lpText = szFileName; //NULL;
lpOptions->ReplaceOption = WAB_REPLACE_PROMPT;
for (ul = 0; ul < ulCount; ul++) { if (lpeudAdrBook[ul].NickName == NULL) { continue; }
Progress.numerator = ul; lpProgressCB(hwnd,&Progress); if (lpeudAdrBook[ul].lpDist !=NULL) { hResult = FillEudDistList(hwnd, lpWabContainer, sProp, lpOptions, lpeudAdrBook, lpsbinary, lpAdrBook, ul); switch (GetScode(hResult)) { case MAPI_E_USER_CANCEL: case MAPI_E_NOT_ENOUGH_MEMORY: goto Error; } } else { hResult = FillMailUser(hwnd, lpWabContainer, sProp, lpOptions, (void *)lpeudAdrBook, lpsbinary, ul,EUDORA); switch (GetScode(hResult)) { case MAPI_E_USER_CANCEL: case MAPI_E_NOT_ENOUGH_MEMORY: goto Error; } } }
Error: if (lpsbinary) { for (ul = 0; ul < ulCount; ul++) { if (lpsbinary[ul].lpb) { LocalFree((HLOCAL)lpsbinary[ul].lpb); lpsbinary[ul].lpb = NULL; } }
LocalFree((HLOCAL)lpsbinary); lpsbinary = NULL; }
return(hResult); }
/******************************************************************************
* FUNCTION NAME:FillEudDistList * * PURPOSE: To create a distribution list in the WAB. * * PARAMETERS: hWnd - hWnd of parent * pAdrBook = pointer to the IADRBOOK interface * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * lpWabContainer = pointer to the IABCONT interface * lpeudAdrBook = pointer to the EUDADRBOOK structure * ul = counter value which holds the position of this address * in the Eudora address book. * sProp = pointer to SPropValue * lpsbinary = pointer to the SBinary array. * * RETURNS: HRESULT ******************************************************************************/ HRESULT FillEudDistList(HWND hwnd, LPABCONT lpWabContainer,LPSPropValue sProp, LPWAB_IMPORT_OPTIONS lpOptions, LPEUDADRBOOK lpeudAdrBook,LPSBinary lpsbinary, LPADRBOOK lpAdrBook,ULONG ul) { LPSPropValue lpNewDLProps = NULL; LPDISTLIST lpDistList = NULL; ULONG cProps, ulObjType; ULONG iCreateTemplate = iconPR_DEF_CREATE_MAILUSER; ULONG iCreateTemplatedl = iconPR_DEF_CREATE_DL; ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT; int i; HRESULT hResult; static LPMAPIPROP lpMailUserWAB = NULL; SPropValue rgProps[4]; LPMAPIPROP lpDlWAB = NULL; LPSBinary lpsbEntry; SBinary sbTemp;
BOOL flag = FALSE; REPLACE_INFO RI = {0}; LPEUDDISTLIST lpTemp = lpeudAdrBook[ul].lpDist;
retry: if (lpsbinary[ul].lpb == NULL) { hResult = CreateDistEntry(lpWabContainer,sProp,ulCreateFlags,&lpMailUserWAB); if (hResult != S_OK) { goto error1; } }
else { hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, lpsbinary[ul].cb, (LPENTRYID)lpsbinary[ul].lpb, (LPIID)&IID_IMAPIProp, MAPI_DEFERRED_ERRORS|MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpMailUserWAB); if (hResult != S_OK) { goto error1; } }
rgProps[0].ulPropTag = PR_DISPLAY_NAME; rgProps[0].Value.lpszA = lpeudAdrBook[ul].NickName; rgProps[1].Value.lpszA = lpeudAdrBook[ul].Description; if (lpeudAdrBook[ul].Description) { rgProps[1].ulPropTag = PR_COMMENT; } else { rgProps[1].ulPropTag = PR_NULL; }
if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 2, rgProps, NULL))) { goto error1; }
if (0 != (hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB, FORCE_SAVE|KEEP_OPEN_READWRITE)))
if (GetScode(hResult) == MAPI_E_COLLISION) { if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) { if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); } lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry;
} if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) { hResult = S_OK; goto error1; }
RI.lpszEmailAddress = NULL; if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) { if (lpeudAdrBook[ul].NickName) { RI.lpszDisplayName = lpeudAdrBook[ul].NickName; RI.lpszEmailAddress = lpeudAdrBook[ul].Address; } else if (lpeudAdrBook[ul].Address) { RI.lpszDisplayName = lpeudAdrBook[ul].Address; } else if (lpeudAdrBook[ul].Description) { RI.lpszDisplayName = lpeudAdrBook[ul].Description; } else { RI.lpszDisplayName = ""; }
RI.ConfirmResult = CONFIRM_ERROR; RI.fExport = FALSE; RI.lpImportOptions = lpOptions;
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ImportReplace), hwnd, ReplaceDialogProc, (LPARAM)&RI);
switch (RI.ConfirmResult) { case CONFIRM_YES: case CONFIRM_YES_TO_ALL: lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry; break;
case CONFIRM_NO: hResult = GetExistEntry(lpWabContainer,lpsbinary, ul, lpeudAdrBook[ul].NickName, NULL); goto error1;
case CONFIRM_ABORT: hResult = ResultFromScode(MAPI_E_USER_CANCEL); goto error1;
default: break; } } }
if (0!= (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB, (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; } goto error1; }
lpsbinary[ul].lpb = (LPBYTE)LocalAlloc(LMEM_FIXED, lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); if (! lpsbinary[ul].lpb) { hResult = hrMemory; goto error1; }
CopyMemory(lpsbinary[ul].lpb, (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb, lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); lpsbinary[ul].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb;
if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; }
hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb, (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb, (LPIID)&IID_IDistList, MAPI_DEFERRED_ERRORS|MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpDistList);
if (hResult != S_OK) { goto error1; }
if (lpNewDLProps) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; }
do { i = lpeudAdrBook[ul].lpDist->AliasID; if (lpeudAdrBook[ul].lpDist->flag == TRUE) {
hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer, sProp[iCreateTemplate].Value.bin.cb, (LPENTRYID)sProp[iCreateTemplate].Value.bin.lpb, ulCreateFlags, &lpMailUserWAB);
if (FAILED(hResult)) { goto error1; }
FillEudDiststruct(rgProps,&lpeudAdrBook[ul]);
if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 3, rgProps, NULL))) { goto error1; }
if (hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB, KEEP_OPEN_READONLY | FORCE_SAVE)) {
if (GetScode(hResult) == MAPI_E_COLLISION) { if (hResult = GetExistEntry(lpWabContainer, &sbTemp, 0, lpeudAdrBook[ul].lpDist->NickName, NULL)) { goto error1; } else { lpsbEntry = &sbTemp; } } else { goto error1; } } else { if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB, (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; } goto error1; } else { lpsbEntry = &(lpNewDLProps[ieidPR_ENTRYID].Value.bin); } }
if (lpMailUserWAB) { // Done with this one
lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; }
if (0 != (hResult = lpDistList->lpVtbl->CreateEntry(lpDistList, lpsbEntry->cb, (LPENTRYID)lpsbEntry->lpb, CREATE_CHECK_DUP_STRICT, &lpDlWAB))) { goto error1; }
hResult = lpDlWAB->lpVtbl->SaveChanges(lpDlWAB, FORCE_SAVE); goto disc; }
if ((LPENTRYID)lpsbinary[i].lpb == NULL && lpeudAdrBook[i].lpDist!=NULL) { FillEudDistList(hwnd, lpWabContainer, sProp, lpOptions, lpeudAdrBook, lpsbinary, lpAdrBook, i); } else { FillMailUser(hwnd, lpWabContainer, sProp, lpOptions, (void *)lpeudAdrBook, lpsbinary, i, EUDORA); }
if (0 != (hResult = lpDistList->lpVtbl->CreateEntry(lpDistList, lpsbinary[i].cb, (LPENTRYID)lpsbinary[i].lpb, CREATE_CHECK_DUP_STRICT, &lpDlWAB))) { goto error1; }
if (0 != (hResult = lpDlWAB->lpVtbl->SaveChanges(lpDlWAB, FORCE_SAVE))) { if (MAPI_E_FOLDER_CYCLE ==hResult) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_LOOPING), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ENTRY_NOIMPORT),MB_OK); } hResult = S_OK; goto error1; }
disc: if (lpNewDLProps) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; }
if (lpDlWAB) { lpDlWAB->lpVtbl->Release(lpDlWAB); lpDlWAB = NULL; }
lpeudAdrBook[ul].lpDist=FreeEuddistlist(lpeudAdrBook[ul].lpDist); } while (lpeudAdrBook[ul].lpDist != NULL);
error1: if (lpNewDLProps) { WABFreeBuffer(lpNewDLProps); } if (lpDistList) { lpDistList->lpVtbl->Release(lpDistList); lpDistList = NULL; }
if (lpDlWAB) { lpDlWAB->lpVtbl->Release(lpDlWAB); lpDlWAB = NULL; }
if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; }
return(hResult); }
/******************************************************************************
* FUNCTION NAME:FillEudWABStruct * * PURPOSE: To fill the SpropValue array. * * PARAMETERS: eudAdrBook = pointer to the EUDADRBOOK structure. * rgProps = pointer to the SpropValue array. * * RETURNS: HRESULT ******************************************************************************/ HRESULT FillEudWABStruct(LPSPropValue rgProps, EUDADRBOOK *eudAdrBook) { HRESULT hr = S_OK;
rgProps[1].Value.lpszA = eudAdrBook->NickName;
if (eudAdrBook->NickName) { rgProps[1].ulPropTag = PR_DISPLAY_NAME; } else { rgProps[1].ulPropTag = PR_NULL; }
rgProps[0].Value.lpszA = eudAdrBook->Address; if (eudAdrBook->Address) { rgProps[0].ulPropTag = PR_EMAIL_ADDRESS; rgProps[2].ulPropTag = PR_ADDRTYPE; rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP); } else { rgProps[0].ulPropTag = PR_NULL; rgProps[2].ulPropTag = PR_NULL; rgProps[2].Value.lpszA = NULL; }
rgProps[3].Value.lpszA = eudAdrBook->Description; if (eudAdrBook->Description) { rgProps[3].ulPropTag = PR_COMMENT; } else { rgProps[3].ulPropTag = PR_NULL; }
rgProps[4].Value.lpszA = eudAdrBook->NickName; if (eudAdrBook->NickName) { rgProps[4].ulPropTag = PR_NICKNAME; } else { rgProps[4].ulPropTag = PR_NULL; }
return(hr); }
/******************************************************************************
* FUNCTION NAME:FillEudDiststruct * * PURPOSE: To fill the SpropValue array. * * PARAMETERS: eudAdrBook = pointer to the EUDADRBOOK structure. * rgProps = pointer to the SpropValue array. * * RETURNS: none ******************************************************************************/ void FillEudDiststruct(LPSPropValue rgProps, EUDADRBOOK *eudAdrBook) { rgProps[1].Value.lpszA = eudAdrBook->lpDist->NickName;
if (eudAdrBook->lpDist->NickName) { rgProps[1].ulPropTag = PR_DISPLAY_NAME; } else { rgProps[1].ulPropTag = PR_NULL; }
rgProps[0].Value.lpszA = eudAdrBook->lpDist->Address; if (eudAdrBook->lpDist->Address) { rgProps[0].ulPropTag = PR_EMAIL_ADDRESS; rgProps[2].ulPropTag = PR_ADDRTYPE; rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP); } else { rgProps[0].ulPropTag = PR_NULL; rgProps[2].ulPropTag = PR_NULL; rgProps[2].Value.lpszA = NULL; } }
/******************************************************************************
* FUNCTION NAME:FreeEuddistlist * * PURPOSE: To free one node from EUDDISTLIST(linked list) * * PARAMETERS: lpDist = pointer to the EUDDISTLIST structure. * * RETURNS: LPEUDDISTLIST , pointer to the next link. ******************************************************************************/ LPEUDDISTLIST FreeEuddistlist(LPEUDDISTLIST lpDist) { LPEUDDISTLIST lpTemp = NULL;
if (lpDist == NULL) { return(NULL); }
lpTemp = lpDist->lpDist;
if (lpDist->NickName) { LocalFree((HLOCAL)lpDist->NickName); } lpDist->NickName = NULL;
if (lpDist->Description) { LocalFree((HLOCAL)lpDist->Description); } lpDist->Description = NULL;
if (lpDist->Address) { LocalFree((HLOCAL)lpDist->Address); } lpDist->Address = NULL;
LocalFree((HLOCAL)lpDist); lpDist = NULL; return(lpTemp); }
/******************************************************************************
* FUNCTION NAME:Getstr * * PURPOSE: Case insensitive equivalent of strstr * * PARAMETERS: szSource = string to search * szToken = string to search for * * RETURNS: pointer to the first occurrence of szToken in szSource ******************************************************************************/ TCHAR* Getstr(TCHAR* szSource, TCHAR* szToken) {
int i, nLength; LPTSTR szdummy = NULL;
szdummy = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szToken)+1)); if (!szdummy) return(NULL); StrCpyN(szdummy, szToken, strlen(szToken)+1); _strupr(szdummy) ; nLength = lstrlen (szdummy) ;
while (*szSource && *(szSource + nLength-1)) { for (i = 0 ;i < nLength ; i++) { TCHAR k = ToUpper(szSource[i]) ; if (szdummy[i] != k) break ; if (i == (nLength - 1)) { LocalFree(szdummy); return(szSource); } } szSource ++ ; }
LocalFree(szdummy); return(NULL); }
/******************************************************************************
* FUNCTION NAME:ShiftAdd * * PURPOSE: To get the address size from a binary file by reading four bytes. * This function reads four consecutive bytes from a buffer and * converts it to a ULONG value. * * PARAMETERS: offset = position in the buffer from where to read * szBuffer = buffer * * RETURNS: ULONG, size ******************************************************************************/ ULONG ShiftAdd(int offset, TCHAR *szBuffer) { ULONG ulSize = 0; int iCounter = 0;
for (iCounter = 3; iCounter > 0; iCounter--) { ulSize |= (unsigned long)((unsigned char)szBuffer[iCounter + offset]); ulSize <<= 8; } ulSize |= (unsigned long)((unsigned char)szBuffer[iCounter + offset]);
return(ulSize); }
/******************************************************************************
*********************Athena Functions***************************************** ****************************************************************************** * FUNCTION NAME:MigrateAthUser * * PURPOSE: To get the installation path of the address book and starts * processing the Athena address book * * PARAMETERS: hwnd = Handle to the parent Window * lpAdrBook = pointer to the IADRBOOK interface * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * * RETURNS: HRESULT ******************************************************************************/ HRESULT MigrateAthUser(HWND hwnd, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) { TCHAR szFileName[MAX_FILE_NAME]; HRESULT hResult;
if (FALSE == GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), ATHENA16)) { return(ResultFromScode(MAPI_E_USER_CANCEL)); }
hResult = ParseAthAddressBook(hwnd, szFileName, lpOptions, lpProgressCB, lpAdrBook);
return(hResult); }
/*****************************************************************************
* FUNCTION NAME:ParseAthAddressBook * * PURPOSE: To get the address book in a file, process addresses and fill WAB. * * PARAMETERS: hwnd = Handle to the parent Window * szFileName = path of the address book. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * lpAdrBook = pointer to the IADRBOOK interface * * RETURNS: HRESULT ******************************************************************************/ HRESULT ParseAthAddressBook(HWND hwnd,LPTSTR szFileName, LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook) { ULONG ulCount=0, ulRead=0, ulFileSize, i, cProps, cError=0; HANDLE hFile = NULL; ABCREC abcrec; TCHAR Buffer[ATHENASTRUCTURE]; LPABCONT lpWabContainer = NULL; HRESULT hResult; static LPSPropValue sProp; WAB_PROGRESS Progress;
lpOptions->ReplaceOption = WAB_REPLACE_PROMPT;
/* Description of athena16 addressbook
Size of each recipient list - 190 bytes Display Name : 81 bytes Address : 81 bytes starting from 28 bytes. */
hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == hFile) { return(ResultFromScode(MAPI_E_NOT_FOUND)); }
ulFileSize = GetFileSize(hFile, NULL);
if ((ulFileSize % ATHENASTRUCTURE) != 0) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR_ADDRESSBOOK), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd, szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR), MB_OK); goto Error; }
if (! ulFileSize) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_NO_ENTRY), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd, szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE), MB_OK); return(ResultFromScode(MAPI_E_CALL_FAILED)); }
ulCount = ulFileSize / ATHENASTRUCTURE; Progress.denominator = ulCount; Progress.numerator = 0; Progress.lpText = NULL;
if (0 != (hResult = OpenWabContainer(&lpWabContainer, lpAdrBook))) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_WAB_ERROR), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_OK); return(hResult); }
if (0 != (hResult = lpWabContainer->lpVtbl->GetProps(lpWabContainer, (LPSPropTagArray)&ptaCon, 0, &cProps, (LPSPropValue *)&sProp))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(sProp); sProp = NULL; } StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_WAB_ERROR), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_OK); return(hResult); }
for (i = 0; i < ulFileSize / ATHENASTRUCTURE; i++) { Progress.numerator = i; lpProgressCB(hwnd, &Progress); if (! ReadFile(hFile, Buffer, ATHENASTRUCTURE, &ulRead, NULL)) { goto Error; } if (NULL == StrCpyN(abcrec.DisplayName, Buffer + ATHENAADROFFSET, MAX_NAME_SIZE + 1)) { goto Error; } if (NULL == StrCpyN(abcrec.EmailAddress, Buffer + ATHENAADROFFSET + MAX_NAME_SIZE + 1, MAX_EMA_SIZE + 1)) { goto Error; } if (strlen(abcrec.DisplayName) == 0 || lstrlen(abcrec.EmailAddress) == 0) { continue; } if (0 != FillAthenaUser(hwnd, lpWabContainer,sProp,lpOptions,&abcrec)) { cError++; }
}
Error: if (sProp) { WABFreeBuffer(sProp); sProp = NULL; } if (lpWabContainer) { lpWabContainer->lpVtbl->Release(lpWabContainer); lpWabContainer = NULL; } if (hFile) { CloseHandle(hFile); }
if (cError) { StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_GERNERIC_ERROR), ARRAYSIZE(szGlobalTempAlloc)); MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_OK); } return(hResult); }
/*****************************************************************************
* FUNCTION NAME:FillAthenaUser * * PURPOSE: To create an entry for the athena16 mail user in the wab. * * PARAMETERS: hwnd - hwnd of parent * lpWabContainer = pointer to the IABCONT interface * sProp = pointer to SPropValue * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * lpabcrec = pointer to the ABCREC structure. * * RETURNS: HRESULT ******************************************************************************/ HRESULT FillAthenaUser(HWND hwnd, LPABCONT lpWabContainer, LPSPropValue sProp, LPWAB_IMPORT_OPTIONS lpOptions, LPABCREC lpabcrec) { ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT; ULONG iCreateTemplate = iconPR_DEF_CREATE_MAILUSER; LPMAPIPROP lpMailUserWAB = NULL; HRESULT hResult; REPLACE_INFO RI = {0}; SPropValue rgProps[3];
retry: hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer, sProp[ iCreateTemplate].Value.bin.cb, (LPENTRYID)sProp[iCreateTemplate].Value.bin.lpb, ulCreateFlags, &lpMailUserWAB); if (FAILED(hResult)) { goto Error; }
rgProps[1].ulPropTag = PR_DISPLAY_NAME; rgProps[1].Value.lpszA = lpabcrec->DisplayName;
rgProps[0].Value.lpszA = lpabcrec->EmailAddress; if (lpabcrec->EmailAddress) { rgProps[0].ulPropTag = PR_EMAIL_ADDRESS; rgProps[2].ulPropTag = PR_ADDRTYPE; rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP); } else { rgProps[0].ulPropTag = PR_NULL; rgProps[2].ulPropTag = PR_NULL; rgProps[2].Value.lpszA = NULL; }
if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 3, rgProps, NULL))) { goto Error; }
hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB, KEEP_OPEN_READONLY | FORCE_SAVE);
if (GetScode(hResult) == MAPI_E_COLLISION) { if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) { if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); } lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry; }
if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) { hResult = S_OK; goto Error; }
if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) { RI.lpszDisplayName = lpabcrec->DisplayName; RI.lpszEmailAddress = lpabcrec->EmailAddress; RI.ConfirmResult = CONFIRM_ERROR; RI.fExport = FALSE; RI.lpImportOptions = lpOptions;
DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_ImportReplace), hwnd, ReplaceDialogProc, (LPARAM)&RI);
switch (RI.ConfirmResult) { case CONFIRM_YES: case CONFIRM_YES_TO_ALL: lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry; break;
case CONFIRM_NO_TO_ALL: case CONFIRM_NO: hResult = hrSuccess; break;
case CONFIRM_ABORT: hResult = ResultFromScode(MAPI_E_USER_CANCEL); goto Error;
default: break; } } }
Error:
if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; }
return(hResult); }
/******************************************************************************
*********************Common Functions***************************************** ****************************************************************************** * FUNCTION NAME:OpenWabContainer * * PURPOSE: To get the pointer to the IABCCONT interface using the * IADRBOOK interface. * * PARAMETERS: lpAdrBook = pointer to the IADRBOOK interface. * lppWabContainer = pointer to the IABCONT interface. * * * RETURNS: HRESULT ******************************************************************************/ HRESULT OpenWabContainer(LPABCONT *lppWabContainer, LPADRBOOK lpAdrBook) { LPENTRYID lpEntryID = NULL; ULONG cbEntryID; ULONG ulObjType; HRESULT hResult;
hResult = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &cbEntryID, &lpEntryID);
if (FAILED(hResult)) { goto Err; }
hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, cbEntryID, lpEntryID, NULL, 0, &ulObjType, (LPUNKNOWN *)lppWabContainer);
Err: if (lpEntryID) { WABFreeBuffer(lpEntryID); } return(hResult); }
/******************************************************************************
* FUNCTION NAME:GetFileToImport * * PURPOSE: To get the path of the address book file using the GetOpenFileName * * PARAMETERS: hwnd = Handle to the parent Window * szFileName = path of the address book * type = containing the value indicating whether it is a EUDORA or * NETSCAPE or ATHENA16 * * RETURNS: BOOL ******************************************************************************/ BOOL GetFileToImport(HWND hwnd, LPTSTR szFileName, DWORD cchFileName, int type) { OPENFILENAME ofn; BOOL ret; TCHAR szFile[MAX_FILE_NAME]; TCHAR szFilter[MAX_FILE_NAME]; ULONG ulSize = 0;
switch (type) { case NETSCAPE: StrCpyN(szFile, LoadStringToGlobalBuffer(IDS_NETSCAPE_PATH), ARRAYSIZE(szFile)); ulSize = SizeLoadStringToGlobalBuffer(IDS_NETSCAPE_FILE); CopyMemory(szFilter, szGlobalAlloc, ulSize); szFilter[ulSize]=szFilter[ulSize+1]='\0';
ofn.lpstrTitle = LoadStringToGlobalBuffer(IDS_NETSCAPE_TITLE); break;
case ATHENA16: StrCpyN(szFile, LoadStringToGlobalBuffer(IDS_ATHENA16_PATH), ARRAYSIZE(szFile)); ulSize = SizeLoadStringToGlobalBuffer(IDS_ATHENA16_FILE); CopyMemory(szFilter, szGlobalAlloc, ulSize); szFilter[ulSize]=szFilter[ulSize+1]='\0';
ofn.lpstrTitle = LoadStringToGlobalBuffer(IDS_ATHENA16_TITLE); break;
case EUDORA: StrCpyN(szFile, LoadStringToGlobalBuffer(IDS_EUDORA_PATH), ARRAYSIZE(szFile)); ulSize = SizeLoadStringToGlobalBuffer(IDS_EUDORA_FILE); CopyMemory(szFilter, szGlobalAlloc, ulSize); szFilter[ulSize]=szFilter[ulSize+1]='\0';
ofn.lpstrTitle = LoadStringToGlobalBuffer(IDS_EUDORA_TITLE); break; }
ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.hInstance = NULL; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof(szFile); ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_HIDEREADONLY; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = NULL; ofn.lCustData = 0; ofn.lpfnHook = ComDlg32DlgProc; ofn.lpTemplateName = NULL;
ret = GetOpenFileName(&ofn);
if (ret) { StrCpyN(szFileName, szFile, cchFileName); }
return(ret); }
INT_PTR CALLBACK ReplaceDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { LPREPLACE_INFO lpRI = (LPREPLACE_INFO)GetWindowLongPtr(hwnd, DWLP_USER);
switch (message) { case WM_INITDIALOG: { TCHAR szFormat[MAX_RESOURCE_STRING + 1]; LPTSTR lpszMessage = NULL; ULONG ids;
SetWindowLongPtr(hwnd, DWLP_USER, lParam); //Save this for future reference
lpRI = (LPREPLACE_INFO)lParam;
if (lpRI->fExport) { ids = lpRI->lpszEmailAddress ? IDS_REPLACE_MESSAGE_EXPORT_2 : IDS_REPLACE_MESSAGE_EXPORT_1; } else { ids = lpRI->lpszEmailAddress ? IDS_REPLACE_MESSAGE_IMPORT_2 : IDS_REPLACE_MESSAGE_IMPORT_1; }
if (LoadString(hInst, ids, szFormat, sizeof(szFormat))) { LPTSTR lpszArg[2] = {lpRI->lpszDisplayName, lpRI->lpszEmailAddress};
if (! FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER, szFormat, 0, 0, //ignored
(LPTSTR)&lpszMessage, 0, (va_list *)lpszArg)) { DebugTrace("FormatMessage -> %u\n", GetLastError()); } else { DebugTrace("Status Message: %s\n", lpszMessage); if (! SetDlgItemText(hwnd, IDC_Replace_Message, lpszMessage)) { DebugTrace("SetDlgItemText -> %u\n", GetLastError()); } LocalFree(lpszMessage); } } return(TRUE); }
case WM_COMMAND : switch (wParam) { case IDCANCEL: lpRI->ConfirmResult = CONFIRM_ABORT; SendMessage(hwnd, WM_CLOSE, 0, 0L); return(0);
case IDCLOSE: case IDNO: lpRI->ConfirmResult = CONFIRM_NO; SendMessage(hwnd, WM_CLOSE, 0, 0L); return(0);
case IDOK: case IDYES: // Set the state of the parameter
lpRI->ConfirmResult = CONFIRM_YES; SendMessage(hwnd, WM_CLOSE, 0, 0); return(0);
case IDC_NoToAll: lpRI->ConfirmResult = CONFIRM_NO_TO_ALL; if (lpRI->fExport) { lpRI->lpExportOptions->ReplaceOption = WAB_REPLACE_NEVER; } else { lpRI->lpImportOptions->ReplaceOption = WAB_REPLACE_NEVER; } SendMessage(hwnd, WM_CLOSE, 0, 0); return(0);
case IDC_YesToAll: lpRI->ConfirmResult = CONFIRM_YES_TO_ALL; if (lpRI->fExport) { lpRI->lpImportOptions->ReplaceOption = WAB_REPLACE_ALWAYS; } else { lpRI->lpExportOptions->ReplaceOption = WAB_REPLACE_ALWAYS; } SendMessage(hwnd, WM_CLOSE, 0, 0); return(0);
case IDM_EXIT: SendMessage(hwnd, WM_DESTROY, 0, 0L); return(0); } break ;
case IDCANCEL: SendMessage(hwnd, WM_CLOSE, 0, 0); break;
case WM_CLOSE: EndDialog(hwnd, FALSE); return(0);
default: return(FALSE); }
return(TRUE); }
INT_PTR CALLBACK ErrorDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { LPERROR_INFO lpEI = (LPERROR_INFO)GetWindowLongPtr(hwnd, DWLP_USER);
switch (message) { case WM_INITDIALOG: { TCHAR szBuffer[MAX_RESOURCE_STRING + 1]; LPTSTR lpszMessage;
SetWindowLongPtr(hwnd, DWLP_USER, lParam); // Save this for future reference
lpEI = (LPERROR_INFO)lParam;
if (LoadString(hInst, lpEI->ids, szBuffer, sizeof(szBuffer))) { LPTSTR lpszArg[2] = {lpEI->lpszDisplayName, lpEI->lpszEmailAddress};
if (! FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER, szBuffer, 0, 0, //ignored
(LPTSTR)&lpszMessage, 0, (va_list *)lpszArg)) { DebugTrace("FormatMessage -> %u\n", GetLastError()); } else { DebugTrace("Status Message: %s\n", lpszMessage); if (! SetDlgItemText(hwnd, IDC_ErrorMessage, lpszMessage)) { DebugTrace("SetDlgItemText -> %u\n", GetLastError()); } LocalFree(lpszMessage); } } return(TRUE); }
case WM_COMMAND : switch (wParam) { case IDCANCEL: lpEI->ErrorResult = ERROR_ABORT; // fall through to close.
case IDCLOSE: // Ignore the contents of the radio button
SendMessage(hwnd, WM_CLOSE, 0, 0L); return(0);
case IDOK: // Get the contents of the radio button
lpEI->lpImportOptions->fNoErrors = (IsDlgButtonChecked(hwnd, IDC_NoMoreError) == 1); lpEI->lpExportOptions->fNoErrors = (IsDlgButtonChecked(hwnd, IDC_NoMoreError) == 1); SendMessage(hwnd, WM_CLOSE, 0, 0); return(0);
case IDM_EXIT: SendMessage(hwnd, WM_DESTROY, 0, 0L); return(0); } break ;
case IDCANCEL: // treat it like a close
SendMessage(hwnd, WM_CLOSE, 0, 0); break;
case WM_CLOSE: EndDialog(hwnd, FALSE); return(0);
default: return(FALSE); }
return(TRUE); }
/******************************************************************************
* FUNCTION NAME:GetRegistryPath * * PURPOSE: To Get path for eudora and netscape installation * * PARAMETERS: szFileName = buffer containing the installation path * type = containing the value indicating whether it is a EUDORA or * NETSCAPE. * * RETURNS: HRESULT ******************************************************************************/ HRESULT GetRegistryPath(LPTSTR szFileName, ULONG cchSize, int type) { HKEY phkResult = NULL; LONG Registry; BOOL bResult; LPOSVERSIONINFO lpVersionInformation ; TCHAR *lpData = NULL, *RegPath = NULL, *path = NULL; unsigned long size = MAX_FILE_NAME; HKEY hKey = (type == NETSCAPE ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); HRESULT hResult = S_OK;
lpData = (TCHAR *)LocalAlloc(LMEM_FIXED, 3*MAX_FILE_NAME); if (!lpData) { hResult = hrMemory; goto error; }
RegPath = (TCHAR *)LocalAlloc(LMEM_FIXED, MAX_FILE_NAME); if (! RegPath) { hResult = hrMemory; goto error; }
path = (TCHAR *)LocalAlloc(LMEM_FIXED, MAX_STRING_SIZE); if (! path) { hResult = hrMemory; goto error; }
switch (type) { case(NETSCAPE): StrCpyN(RegPath, LoadStringToGlobalBuffer(IDS_NETSCAPE_REGKEY), MAX_FILE_NAME); StrCpyN(path, LoadStringToGlobalBuffer(IDS_NETSCAPE_ADDRESS_PATH), MAX_STRING_SIZE); break;
case(EUDORA): StrCpyN(RegPath, LoadStringToGlobalBuffer(IDS_EUDORA_32_REGKEY), MAX_FILE_NAME); StrCpyN(path, LoadStringToGlobalBuffer(IDS_EUDORA_ADDRESS_PATH), MAX_STRING_SIZE); break; }
lpVersionInformation = (LPOSVERSIONINFO)LocalAlloc(LMEM_FIXED, sizeof(OSVERSIONINFO));
if (!lpVersionInformation) { hResult = hrMemory; goto error; }
lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if ((bResult = GetVersionEx(lpVersionInformation)) == FALSE) { hResult = E_FAIL; goto error; }
switch (lpVersionInformation->dwPlatformId) {
case (VER_PLATFORM_WIN32s): hResult = E_FAIL; goto error; break;
case (VER_PLATFORM_WIN32_WINDOWS): case (VER_PLATFORM_WIN32_NT): Registry = RegOpenKeyEx(hKey,RegPath, 0, KEY_QUERY_VALUE, &phkResult); // bug 35949 - not finding the correct key under HKLM for Netscape
// Try again under HKCU
if (type == NETSCAPE && Registry != ERROR_SUCCESS) { Registry = RegOpenKeyEx(HKEY_CURRENT_USER, RegPath, 0, KEY_QUERY_VALUE, &phkResult); } if (Registry != ERROR_SUCCESS) { hResult = E_FAIL; goto error; } break; }
Registry = RegQueryValueEx(phkResult, path, NULL, NULL, (LPBYTE)lpData, &size); if (Registry != ERROR_SUCCESS) { hResult = E_FAIL; goto error; }
StrCpyN(szFileName,lpData, cchSize);
if (type == EUDORA) { // this key value contains three items:
// Path-to-Eudora,exe<space>Path-to-Eudora-Dir<space>Path-to-ini-file
// We want the middle entry only
LPTSTR lp = szFileName; while (*lp && ! IsSpace(lp)) { lp = CharNext(lp); } if (IsSpace(lp)) { // overwrite everything upto the first space
lp = CharNext(lp); StrCpyN(szFileName, lp, cchSize);
// Find the next space and terminate the filename string there
lp = szFileName; while (*lp && ! IsSpace(lp)) { lp = CharNext(lp); } if (IsSpace(lp)) { *lp = '\0'; } } }
error: if (phkResult) { RegCloseKey(phkResult); } if (hKey) { RegCloseKey(hKey); } if (lpVersionInformation) { LocalFree((HLOCAL)lpVersionInformation); } if (lpData) { LocalFree((HLOCAL)lpData); } if (RegPath) { LocalFree((HLOCAL)RegPath); } if (path) { LocalFree((HLOCAL)path); }
return(hResult);
}
/******************************************************************************
* FUNCTION NAME:GetExistEntry * * PURPOSE: To fill the Sbinary array for an already existig entry in the WAB * for which user has selected NO as replace option. * * PARAMETERS: lpWabContainer = pointer to the IABCONT interface. * lpsbinary = pointer to SBinary array. * ucount = position in the SBinary array where the ENTRY_ID has * to be filled. * szDisplayName = display nmae of the user that has to be searched. * szNickName = if no DisplayName, use NickName * * RETURNS: HRESULT ******************************************************************************/ HRESULT GetExistEntry(LPABCONT lpWabContainer, LPSBinary lpsbinary, ULONG ucount, LPTSTR szDisplayName, LPTSTR szNickName) { HRESULT hResult; LPMAPITABLE lpMapiTable = NULL; SRestriction Restriction; SPropValue pProp; LPSRowSet lpsrowset=NULL; SPropertyRestriction PropertyRestriction; BOOKMARK bkmark;
bkmark = BOOKMARK_BEGINNING; pProp.ulPropTag = PR_DISPLAY_NAME; if (szDisplayName && lstrlen(szDisplayName)) { pProp.Value.lpszA = szDisplayName; } else if (szNickName && lstrlen(szNickName)) { pProp.Value.lpszA = szNickName; }
PropertyRestriction.relop=RELOP_EQ; PropertyRestriction.ulPropTag=PR_DISPLAY_NAME; PropertyRestriction.lpProp=&pProp;
Restriction.rt=RES_PROPERTY; Restriction.res.resProperty=PropertyRestriction;
if (0 != (hResult = lpWabContainer->lpVtbl->GetContentsTable(lpWabContainer, MAPI_DEFERRED_ERRORS, &lpMapiTable))) { goto error; }
if (0 != (hResult = lpMapiTable->lpVtbl->FindRow(lpMapiTable, &Restriction, bkmark, 0))) { goto error; }
if (0 != (hResult = lpMapiTable->lpVtbl->SetColumns(lpMapiTable, (LPSPropTagArray)&ptaEid, 0))) { goto error; }
if (0 != (hResult = lpMapiTable->lpVtbl->QueryRows(lpMapiTable, 1, 0, &lpsrowset))) { goto error; }
if (! (lpsbinary[ucount].lpb = (LPBYTE)LocalAlloc(LMEM_FIXED, lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb))) { hResult = hrMemory; goto error; } CopyMemory(lpsbinary[ucount].lpb, lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb, lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb); lpsbinary[ucount].cb = lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb;
error: if (lpsrowset) { FreeRowSet(lpsrowset); } if (lpMapiTable) { lpMapiTable->lpVtbl->Release(lpMapiTable); lpMapiTable = NULL; }
return(hResult); }
/******************************************************************************
* FUNCTION NAME:FreeRowSet * * PURPOSE: To free the srowset structure. * * RETURNS: none. ******************************************************************************/ void FreeRowSet(LPSRowSet lpRows) { ULONG cRows;
if (! lpRows) { return; }
for (cRows = 0; cRows < lpRows->cRows; ++cRows) { WABFreeBuffer(lpRows->aRow[cRows].lpProps); }
WABFreeBuffer(lpRows); }
/******************************************************************************
* FUNCTION NAME:SizeLoadStringToGlobalBuffer * * PURPOSE: Loads a string resource into the globall alloc buffer * and returns the size, not the string * * PARAMETERS: StringID - String identifier to load * * RETURNS: ULONG number of characters loaded * * created: Vikramm 02/04/97 * Bug: 17928 - trash in OpenFileDialog dropdown * caused because StrCpyN cant copy strings with * \0 in them. Need to do a copy memory ******************************************************************************/ ULONG SizeLoadStringToGlobalBuffer(int StringID) { ULONG ulSize = 0; ulSize = LoadString(hInst, StringID, szGlobalAlloc, sizeof(szGlobalAlloc)); return(ulSize); }
/******************************************************************************
* FUNCTION NAME:LoadStringToGlobalBuffer * * PURPOSE: Loads a string resource * * PARAMETERS: StringID - String identifier to load * * RETURNS: LPTSTR, string that is loaded. ******************************************************************************/ LPTSTR LoadStringToGlobalBuffer(int StringID) { ULONG ulSize = 0;
ulSize = LoadString(hInst, StringID, szGlobalAlloc, sizeof(szGlobalAlloc)); return(szGlobalAlloc); }
/******************************************************************************
* FUNCTION NAME:FillMailUser * * PURPOSE: To create a mail user in the WAB for NetScape/Eudora . * * PARAMETERS: hwnd - hwnd of parent * lpWabContainer = pointer to the IABCONT interface. * sProp = pointer to SPropValue which contains ENTRY_ID. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure * lpadrbook = pointer to NSADRBOOK/EUDADRBOOK typecasted to void* * lpsbinary = pointer to an array of SBinary structure. * type = containing the value indicating whether it is a EUDORA or * NETSCAPE. * ul = offset for Eudora in EUDADRBOOK array. * * RETURNS: HRESULT ******************************************************************************/ HRESULT FillMailUser(HWND hwnd, LPABCONT lpWabContainer, LPSPropValue sProp, LPWAB_IMPORT_OPTIONS lpOptions, void *lpadrbook, LPSBinary lpsbinary, ULONG ul, int type) { ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT; ULONG iCreateTemplate = iconPR_DEF_CREATE_MAILUSER; LPSPropValue lpNewDLProps = NULL; LPMAPIPROP lpMailUserWAB = NULL; ULONG cProps; HRESULT hResult; REPLACE_INFO RI; SPropValue rgProps[5]; LPEUDADRBOOK lpEudAdrBook = NULL; LPNSADRBOOK lpNsAdrBook = NULL;
if (NETSCAPE == type) { lpNsAdrBook = (LPNSADRBOOK)lpadrbook; } else { lpEudAdrBook = (LPEUDADRBOOK)lpadrbook; }
retry: if (EUDORA == type) { if (lpsbinary[ul].lpb != NULL) { return(S_OK); } }
hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer, sProp[iCreateTemplate].Value.bin.cb, (LPENTRYID)sProp[iCreateTemplate].Value.bin.lpb, ulCreateFlags, &lpMailUserWAB);
if (FAILED(hResult)) { goto Error; }
if (NETSCAPE == type) { FillWABStruct(rgProps,lpNsAdrBook); if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 5, rgProps, NULL))) goto Error; } else { FillEudWABStruct(rgProps,&lpEudAdrBook[ul]); if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 4, rgProps, NULL))) goto Error; }
hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB, KEEP_OPEN_READONLY | FORCE_SAVE);
if (GetScode(hResult) == MAPI_E_COLLISION) { if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) { if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); } lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry; }
if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) { hResult = S_OK; goto Error; }
if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) { RI.lpszEmailAddress = NULL; if (NETSCAPE == type) { if (lpNsAdrBook->Entry) { RI.lpszDisplayName = lpNsAdrBook->Entry; RI.lpszEmailAddress = lpNsAdrBook->Address; } else if (lpNsAdrBook->NickName) { RI.lpszDisplayName = lpNsAdrBook->NickName; RI.lpszEmailAddress = lpNsAdrBook->Address; } else if (lpNsAdrBook->Address) { RI.lpszDisplayName = lpNsAdrBook->Address; } else if (lpNsAdrBook->Description) { RI.lpszDisplayName = lpNsAdrBook->Description; } else { RI.lpszDisplayName = ""; } } else { RI.lpszDisplayName = lpEudAdrBook[ul].NickName; RI.lpszEmailAddress = lpEudAdrBook[ul].Address; } RI.ConfirmResult = CONFIRM_ERROR; RI.lpImportOptions = lpOptions;
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ImportReplace), hwnd, ReplaceDialogProc, (LPARAM)&RI);
switch (RI.ConfirmResult) { case CONFIRM_YES: case CONFIRM_YES_TO_ALL: lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; ulCreateFlags |= CREATE_REPLACE; goto retry; break;
case CONFIRM_ABORT: hResult = ResultFromScode(MAPI_E_USER_CANCEL); goto Error;
case CONFIRM_NO: if (NETSCAPE == type) { if (lpNsAdrBook->Sbinary == TRUE) GetExistEntry(lpWabContainer, lpsbinary, lpNsAdrBook->AliasID, lpNsAdrBook->Entry, lpNsAdrBook->NickName); } else hResult = GetExistEntry(lpWabContainer,lpsbinary,ul, lpEudAdrBook[ul].NickName, NULL); goto Error;
default: break; } } }
if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB, (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) { if (hResult == MAPI_W_ERRORS_RETURNED) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; } goto Error; }
if (NETSCAPE == type) { if (lpNsAdrBook->Sbinary == TRUE) { lpsbinary[lpNsAdrBook->AliasID].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); if (!lpsbinary[lpNsAdrBook->AliasID].lpb) { hResult = hrMemory; goto Error; } CopyMemory(lpsbinary[lpNsAdrBook->AliasID].lpb, (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); lpsbinary[lpNsAdrBook->AliasID].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb; } } else { lpsbinary[ul].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); if (!lpsbinary[ul].lpb) { hResult = hrMemory; goto Error; } CopyMemory(lpsbinary[ul].lpb,(LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb); lpsbinary[ul].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb; }
Error:
if (lpNewDLProps) { WABFreeBuffer(lpNewDLProps); lpNewDLProps = NULL; }
if (lpMailUserWAB) { lpMailUserWAB->lpVtbl->Release(lpMailUserWAB); lpMailUserWAB = NULL; }
return(hResult); }
/******************************************************************************
* FUNCTION NAME:ComDlg32DlgProc * * PURPOSE: Change the title of open button to Import. * * PARAMETERS: * * RETURNS: BOOL ******************************************************************************/ INT_PTR CALLBACK ComDlg32DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
if (LoadString(hInst, IDS_IMPORT_BUTTON, szBuffer, sizeof(szBuffer))) { SetDlgItemText(GetParent(hDlg), 1, szBuffer); } break; }
default: return(FALSE); } return(TRUE); }
const static char c_szReg[] = "Reg"; const static char c_szUnReg[] = "UnReg"; const static char c_szAdvPackDll[] = "ADVPACK.DLL";
static char c_szWABIMP[] = "WABIMP";
HRESULT CallRegInstall(LPCSTR szSection) { HRESULT hr; HINSTANCE hAdvPack; REGINSTALL pfnri; char szWabimpDll[MAX_PATH]; STRENTRY seReg; STRTABLE stReg;
hr = E_FAIL;
hAdvPack = LoadLibraryA(c_szAdvPackDll); if (hAdvPack != NULL) { // Get Proc Address for registration util
pfnri = (REGINSTALL)GetProcAddress(hAdvPack, achREGINSTALL); if (pfnri != NULL) {
GetModuleFileName(hInstApp, szWabimpDll, sizeof(szWabimpDll)); seReg.pszName = c_szWABIMP; seReg.pszValue = szWabimpDll; stReg.cEntries = 1; stReg.pse = &seReg;
// Call the self-reg routine
hr = pfnri(hInstApp, szSection, &stReg); }
FreeLibrary(hAdvPack); }
return(hr); }
STDAPI DllRegisterServer(void) { return(CallRegInstall(c_szReg)); }
STDAPI DllUnregisterServer(void) { return(CallRegInstall(c_szUnReg)); }
/***************************************************************************
Name : ShowMessageBoxParam
Purpose : Generic MessageBox displayer
Parameters: hWndParent - Handle of message box parent MsgID - resource id of message string ulFlags - MessageBox flags ... - format parameters
Returns : MessageBox return code
***************************************************************************/ int __cdecl ShowMessageBoxParam(HWND hWndParent, int MsgId, int ulFlags, ...) { TCHAR szBuf[MAX_RESOURCE_STRING + 1] = ""; TCHAR szCaption[MAX_PATH] = ""; LPTSTR lpszBuffer = NULL; int iRet = 0; va_list vl;
va_start(vl, ulFlags);
LoadString(hInst, MsgId, szBuf, sizeof(szBuf)); if (FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, szBuf, 0,0, // ignored
(LPTSTR)&lpszBuffer, sizeof(szBuf), // MAX_UI_STR
(va_list *)&vl)) { TCHAR szCaption[MAX_PATH];
GetWindowText(hWndParent, szCaption, sizeof(szCaption)); if (! lstrlen(szCaption)) { // if no caption get the parents caption - this is necessary for property sheets
GetWindowText(GetParent(hWndParent), szCaption, sizeof(szCaption)); if (! lstrlen(szCaption)) //if still not caption, use empty title
szCaption[0] = (TCHAR)'\0'; } iRet = MessageBox(hWndParent, lpszBuffer, szCaption, ulFlags); LocalFree(lpszBuffer); } va_end(vl); return(iRet); }
//$$//////////////////////////////////////////////////////////////////////
//
// LoadAllocString - Loads a string resource and allocates enough
// memory to hold it.
//
// StringID - String identifier to load
//
// returns the LocalAlloc'd, null terminated string. Caller is responsible
// for LocalFree'ing this buffer. If the string can't be loaded or memory
// can't be allocated, returns NULL.
//
//////////////////////////////////////////////////////////////////////////
LPTSTR LoadAllocString(int StringID) { ULONG ulSize = 0; LPTSTR lpBuffer = NULL; TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
ulSize = LoadString(hInst, StringID, szBuffer, sizeof(szBuffer));
if (ulSize && (lpBuffer = LocalAlloc(LPTR, ulSize + 1))) { StrCpyN(lpBuffer, szBuffer, ulSize + 1); }
return(lpBuffer); }
/***************************************************************************
Name : FormatAllocFilter
Purpose : Loads file filter name string resources and formats them with their file extension filters
Parameters: StringID1 - String identifier to load (required) szFilter1 - file name filter, ie, "*.vcf" (required) StringID2 - String identifier (optional) szFilter2 - file name filter (optional) StringID3 - String identifier (optional) szFilter3 - file name filter (optional)
Returns : LocalAlloc'd, Double null terminated string. Caller is responsible for LocalFree'ing this buffer. If the string can't be loaded or memory can't be allocated, returns NULL.
***************************************************************************/ LPTSTR FormatAllocFilter(int StringID1, LPCTSTR lpFilter1, int StringID2, LPCTSTR lpFilter2, int StringID3, LPCTSTR lpFilter3) { LPTSTR lpFileType1 = NULL, lpFileType2 = NULL, lpFileType3 = NULL; LPTSTR lpTemp; LPTSTR lpBuffer = NULL; // All string sizes include null
ULONG cbFileType1 = 0, cbFileType2 = 0, cbFileType3 = 0; ULONG cbFilter1 = 0, cbFilter2 = 0, cbFilter3 = 0; ULONG cbBuffer;
cbBuffer = cbFilter1 = lstrlen(lpFilter1) + 1; if (! (lpFileType1 = LoadAllocString(StringID1))) { DebugTrace("LoadAllocString(%u) failed\n", StringID1); return(NULL); } cbBuffer += (cbFileType1 = lstrlen(lpFileType1) + 1); if (lpFilter2 && StringID2) { cbBuffer += (cbFilter2 = lstrlen(lpFilter2) + 1); if (! (lpFileType2 = LoadAllocString(StringID2))) { DebugTrace("LoadAllocString(%u) failed\n", StringID2); } else { cbBuffer += (cbFileType2 = lstrlen(lpFileType2) + 1); } } if (lpFilter3 && StringID3) { cbBuffer += (cbFilter3 = lstrlen(lpFilter3) + 1); if (! (lpFileType3 = LoadAllocString(StringID3))) { DebugTrace("LoadAllocString(%u) failed\n", StringID3); } else { cbBuffer += (cbFileType3 = lstrlen(lpFileType3) + 1); } } cbBuffer++;
Assert(cbBuffer == cbFilter1 + cbFilter2 + cbFilter3 + cbFileType1 + cbFileType2 + cbFileType3 + 1);
if (lpBuffer = LocalAlloc(LPTR, cbBuffer * sizeof(TCHAR))) { lpTemp = lpBuffer; StrCpyN(lpTemp, lpFileType1, cbBuffer); lpTemp += cbFileType1; cbBuffer -= cbFileType1; StrCpyN(lpTemp, lpFilter1, cbBuffer); lpTemp += cbFilter1; cbBuffer -= cbFilter1; LocalFree(lpFileType1); if (cbFileType2 && cbFilter2) { StrCpyN(lpTemp, lpFileType2, cbBuffer); lpTemp += cbFileType2; cbBuffer -= cbFileType2; StrCpyN(lpTemp, lpFilter2, cbBuffer); lpTemp += cbFilter2; cbBuffer -= cbFilter2; LocalFree(lpFileType2); } if (cbFileType3 && cbFilter3) { StrCpyN(lpTemp, lpFileType3, cbBuffer); lpTemp += cbFileType3; cbBuffer -= cbFileType3; StrCpyN(lpTemp, lpFilter3, cbBuffer); lpTemp += cbFilter3; cbBuffer -= cbFilter3; LocalFree(lpFileType3); }
*lpTemp = '\0'; }
return(lpBuffer); }
/***************************************************************************
Name : SaveFileDialog
Purpose : Presents a Save filename dialog
Parameters: hWnd = parent window handle szFileName = in/out filename buffer (must be MAX_PATH + 1) lpFilter1 = First filename filter string idsFileType1 = First filename type string id lpFilter2 = Second filename filter string (or NULL) idsFileType2 = Second filename type string id lpFilter3 = Third filename filter string (or NULL) idsFileType3 = Third filename type string id lpDefExt = default extension string ulFlags = GetSaveFileName flags hInst = instance handle idsTitle = dialog title string id idsSaveButton = Save button string id (0 = default)
Returns : HRESULT
***************************************************************************/ HRESULT SaveFileDialog(HWND hWnd, LPTSTR szFileName, LPCTSTR lpFilter1, ULONG idsFileType1, LPCTSTR lpFilter2, ULONG idsFileType2, LPCTSTR lpFilter3, ULONG idsFileType3, LPCTSTR lpDefExt, ULONG ulFlags, HINSTANCE hInst, ULONG idsTitle, ULONG idsSaveButton) { LPTSTR lpFilterName; OPENFILENAME ofn; HRESULT hResult = hrSuccess;
if (! (lpFilterName = FormatAllocFilter(idsFileType1, lpFilter1, idsFileType2, lpFilter2, idsFileType3, lpFilter3))) { return(ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY)); }
ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hWnd; ofn.hInstance = hInst; ofn.lpstrFilter = lpFilterName; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = NULL; // lpTitle;
ofn.Flags = ulFlags; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = lpDefExt; ofn.lCustData = 0; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL;
if (! GetSaveFileName(&ofn)) { DebugTrace("GetSaveFileName cancelled\n"); hResult = ResultFromScode(MAPI_E_USER_CANCEL); }
if(lpFilterName) LocalFree(lpFilterName);
return(hResult); }
/***************************************************************************
Name : OpenFileDialog
Purpose : Presents a open filename dialog
Parameters: hWnd = parent window handle szFileName = in/out filename buffer (must be MAX_PATH + 1) lpFilter1 = First filename filter string idsFileType1 = First filename type string id lpFilter2 = Second filename filter string (or NULL) idsFileType2 = Second filename type string id lpFilter3 = Third filename filter string (or NULL) idsFileType3 = Third filename type string id lpDefExt = default extension string ulFlags = GetOpenFileName flags hInst = instance handle idsTitle = dialog title string id idsSaveButton = Save button string id (0 = default)
Returns : HRESULT
***************************************************************************/ HRESULT OpenFileDialog(HWND hWnd, LPTSTR szFileName, LPCTSTR lpFilter1, ULONG idsFileType1, LPCTSTR lpFilter2, ULONG idsFileType2, LPCTSTR lpFilter3, ULONG idsFileType3, LPCTSTR lpDefExt, ULONG ulFlags, HINSTANCE hInst, ULONG idsTitle, ULONG idsOpenButton) { LPTSTR lpFilterName; OPENFILENAME ofn; HRESULT hResult = hrSuccess;
if (! (lpFilterName = FormatAllocFilter(idsFileType1, lpFilter1, idsFileType2, lpFilter2, idsFileType3, lpFilter3))) { return(ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY)); }
ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hWnd; ofn.hInstance = hInst; ofn.lpstrFilter = lpFilterName; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = NULL; // lpTitle;
ofn.Flags = ulFlags; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = lpDefExt; ofn.lCustData = 0; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL;
if (! GetOpenFileName(&ofn)) { DebugTrace("GetOpenFileName cancelled\n"); hResult = ResultFromScode(MAPI_E_USER_CANCEL); }
if(lpFilterName) LocalFree(lpFilterName);
return(hResult); }
/***************************************************************************
Name : CountRows
Purpose : Count the rows in a table (restriction aware)
Parameters: lpTable = table object fMAPI = TRUE if MAPI table, FALSE if WAB table
Returns : returns number of rows in the restricted table
Comment : Leaves the table pointer at the beginning. I'd use GetRowCount, but it is not aware of restrictions.
***************************************************************************/ #define COUNT_BATCH 50
ULONG CountRows(LPMAPITABLE lpTable, BOOL fMAPI) { ULONG cRows; ULONG cTotal = 0; HRESULT hResult; LPSRowSet lpRow = NULL;
#ifdef DEBUG
DWORD dwTickCount = GetTickCount(); DebugTrace(">>>>> Counting Table Rows...\n"); #endif // DEBUG
cRows = 1; while (cRows) { if (hResult = lpTable->lpVtbl->QueryRows(lpTable, COUNT_BATCH, // 50 row's at a time
0, // ulFlags
&lpRow)) { DebugTrace("CountRows:QueryRows -> %x\n", GetScode(hResult)); break; }
if (lpRow) { if (cRows = lpRow->cRows) { // yes, single '='
cTotal += cRows; } // else, drop out of loop, we're done.
if (fMAPI) { FreeProws(lpRow); } else { WABFreeProws(lpRow); } lpRow = NULL; } else { cRows = 0; // done
} }
if (HR_FAILED(hResult = lpTable->lpVtbl->SeekRow(lpTable, BOOKMARK_BEGINNING, 0, NULL))) { DebugTrace("CountRows:SeekRow -> %x\n", GetScode(hResult)); }
#ifdef DEBUG
DebugTrace(">>>>> Done Counting Table Rows... %u milliseconds\n", GetTickCount() - dwTickCount); #endif
return(cTotal); }
/***************************************************************************
Name : WABFreePadrlist
Purpose : Free an adrlist and it's property arrays
Parameters: lpBuffer = buffer to free
Returns : SCODE
Comment :
***************************************************************************/ void WABFreePadrlist(LPADRLIST lpAdrList) { ULONG iEntry;
if (lpAdrList) { for (iEntry = 0; iEntry < lpAdrList->cEntries; ++iEntry) { if (lpAdrList->aEntries[iEntry].rgPropVals) { WABFreeBuffer(lpAdrList->aEntries[iEntry].rgPropVals); } } WABFreeBuffer(lpAdrList); } }
/***************************************************************************
Name : WABFreeProws
Purpose : Destroys an SRowSet structure.
Parameters: prows -> SRowSet to free
Returns : none
Comment :
***************************************************************************/ void WABFreeProws(LPSRowSet prows) { register ULONG irow;
if (! prows) { return; }
for (irow = 0; irow < prows->cRows; ++irow) { WABFreeBuffer(prows->aRow[irow].lpProps); } WABFreeBuffer(prows); }
/***************************************************************************
Name : FindAdrEntryID
Purpose : Find the PR_ENTRYID in the Nth ADRENTRY of an ADRLIST
Parameters: lpAdrList -> AdrList index = which ADRENTRY to look at
Returns : return pointer to the SBinary structure of the ENTRYID value
Comment :
***************************************************************************/ LPSBinary FindAdrEntryID(LPADRLIST lpAdrList, ULONG index) { LPADRENTRY lpAdrEntry; ULONG i;
if (lpAdrList && index < lpAdrList->cEntries) {
lpAdrEntry = &(lpAdrList->aEntries[index]);
for (i = 0; i < lpAdrEntry->cValues; i++) { if (lpAdrEntry->rgPropVals[i].ulPropTag == PR_ENTRYID) { return((LPSBinary)&lpAdrEntry->rgPropVals[i].Value); } } } return(NULL); }
/***************************************************************************
Name : FindProperty
Purpose : Finds a property in a proparray
Parameters: cProps = number of props in the array lpProps = proparray ulPropTag = property tag to look for
Returns : array index of property or NOT_FOUND
Comment :
***************************************************************************/ ULONG FindProperty(ULONG cProps, LPSPropValue lpProps, ULONG ulPropTag) { register ULONG i;
for (i = 0; i < cProps; i++) { if (lpProps[i].ulPropTag == ulPropTag) { return(i); } }
return(NOT_FOUND); }
/***************************************************************************
Name : FindStringInProps
Purpose : Find the string property in the property value array
Parameters: lpspv -> property value array ulcProps = size of array ulPropTag
Returns : return pointer to the string pointer in the array. If the property doesn't exist or has error value, return NULL.
Comment :
***************************************************************************/ LPTSTR FindStringInProps(LPSPropValue lpspv, ULONG ulcProps, ULONG ulPropTag) { ULONG i;
if (lpspv) { for (i = 0; i < ulcProps; i++) { if (lpspv[i].ulPropTag == ulPropTag) { return(lpspv[i].Value.LPSZ); } } } return(NULL); }
/***************************************************************************
Name : PropStringOrNULL
Purpose : Returns the value of a property or NULL if it is an error
Parameters: lpspv -> property value to check and return
Returns : pointer to value string or NULL
***************************************************************************/ LPTSTR PropStringOrNULL(LPSPropValue lpspv) { return(PROP_ERROR((*lpspv)) ? NULL : lpspv->Value.LPSZ); }
/***************************************************************************
Name : FreeSeenList
Purpose : Frees the SeenList
Parameters: none
Returns : none
Comment :
***************************************************************************/ void FreeSeenList(void) { ULONG i;
Assert((lpEntriesSeen && ulEntriesSeen) || (! lpEntriesSeen && ! ulEntriesSeen));
for (i = 0; i < ulEntriesSeen; i++) { if (lpEntriesSeen[i].sbinPAB.lpb) { LocalFree(lpEntriesSeen[i].sbinPAB.lpb); } if (lpEntriesSeen[i].sbinWAB.lpb) { LocalFree(lpEntriesSeen[i].sbinWAB.lpb); } }
if (lpEntriesSeen) { LocalFree(lpEntriesSeen); } lpEntriesSeen = NULL; ulEntriesSeen = 0; ulMaxEntries = 0; }
/***************************************************************************
Name : GetEMSSMTPAddress
Purpose : Get the Exchange SMTP address for this object
Parameters: lpObject -> Object
Returns : lpSMTP -> returned buffer containing SMTP address (must be MAPIFree'd by caller.) lpBase = base allocation to alloc more onto
Comment : What a mess! EMS changed their name id's and guids between 4.0 and 4.5. They also added a fixed ID property containing just the SMTP address in 4.5.
***************************************************************************/ const GUID guidEMS_AB_40 = { // GUID for EMS 4.0 addresses
0x48862a09, 0xf786, 0x0114, {0x02, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; const GUID guidEMS_AB_45 = { // GUID for EMS 4.5 addresses
0x48862a08, 0xf786, 0x0114, {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; #define ID_EMS_AB_PROXY_ADDRESSES_40 0x10052
#define ID_EMS_AB_PROXY_ADDRESSES_45 0x25281
// New MAPI property, found on EX 4.5 and later
#define PR_PRIMARY_SMTP_ADDRESS PROP_TAG(PT_TSTRING, 0x39FE)
LPTSTR GetEMSSMTPAddress(LPMAPIPROP lpObject, LPVOID lpBase) { ULONG ulPropTag40 = 0, ulPropTag45 = 0; MAPINAMEID mnidT[2]; LPMAPINAMEID lpmnid = (LPMAPINAMEID)&mnidT; LPSPropTagArray lptaga = NULL; HRESULT hResult; LPTSTR lpSMTP = NULL, lpAddr; LPSPropValue lpspv = NULL; ULONG i, i40 = 0, i45 = 0; SLPSTRArray MVString; SizedSPropTagArray(3, spta); ULONG cValues; SCODE sc;
#ifdef TEST_STUFF
MAPIDebugNamedProps(lpObject, "Exchange Address"); #endif
mnidT[0].lpguid = (LPGUID)&guidEMS_AB_40; mnidT[0].ulKind = MNID_ID; mnidT[0].Kind.lID = ID_EMS_AB_PROXY_ADDRESSES_40;
if (HR_FAILED(hResult = lpObject->lpVtbl->GetIDsFromNames(lpObject, 1, // Just one name
&lpmnid, // &-of because this is an array
0, // This is where MAPI_CREATE might go
&lptaga))) { DebugTrace("GetEMSNamedPropTag:GetIDsFromNames -> %x", GetScode(hResult)); }
if (lptaga) { if (lptaga->cValues >= 1 && (PROP_TYPE(lptaga->aulPropTag[0]) != PT_ERROR)) { ulPropTag40 = lptaga->aulPropTag[0]; } MAPIFreeBuffer(lptaga); }
// Yes, I should be doing them both at once, but the PAB fails if you call
// GetIDsFromNames with ulCount > 1!
mnidT[0].lpguid = (LPGUID)&guidEMS_AB_45; mnidT[0].ulKind = MNID_ID; mnidT[0].Kind.lID = ID_EMS_AB_PROXY_ADDRESSES_45;
if (HR_FAILED(hResult = lpObject->lpVtbl->GetIDsFromNames(lpObject, 1, // Just one name
&lpmnid, // &-of because this is an array
0, // This is where MAPI_CREATE might go
&lptaga))) { DebugTrace("GetEMSNamedPropTag:GetIDsFromNames -> %x", GetScode(hResult)); }
if (lptaga) { if (lptaga->cValues >= 1 && (PROP_TYPE(lptaga->aulPropTag[0]) != PT_ERROR)) { ulPropTag45 = lptaga->aulPropTag[0]; } MAPIFreeBuffer(lptaga); }
spta.aulPropTag[0] = PR_PRIMARY_SMTP_ADDRESS; i = 1; if (ulPropTag40) { i40 = i++; spta.aulPropTag[i40] = CHANGE_PROP_TYPE(ulPropTag40, PT_MV_TSTRING); } if (ulPropTag45) { i45 = i++; spta.aulPropTag[i45] = CHANGE_PROP_TYPE(ulPropTag45, PT_MV_TSTRING); } spta.cValues = i;
// Now, get the props from the object
if (! HR_FAILED(hResult = lpObject->lpVtbl->GetProps(lpObject, (LPSPropTagArray)&spta, 0, &cValues, &lpspv))) { // Found one or more of the properties. Look up the SMTP address.
if (! PROP_ERROR(lpspv[0])) { if (sc = MAPIAllocateMore((lstrlen(lpspv[0].Value.LPSZ) + 1)* sizeof(TCHAR), lpBase, &lpSMTP)) { DebugTrace("GetEMSSMTPAddress:MAPIAllocateMore -> %x\n", sc); hResult = ResultFromScode(sc); goto done; } StrCpyN(lpSMTP, lpspv[0].Value.LPSZ, lstrlen(lpspv[0].Value.LPSZ) + 1); goto done; } else if (i40 && ! PROP_ERROR(lpspv[i40])) { // 4.0 version
MVString = lpspv[i40].Value.MVSZ; } else if (i45 && ! PROP_ERROR(lpspv[i45])) { // 4.5 version
MVString = lpspv[i45].Value.MVSZ; } else { goto done; }
for (i = 0; i < MVString.cValues; i++) { lpAddr = MVString.LPPSZ[i]; if ((lpAddr[0] == 'S') && (lpAddr[1] == 'M') && (lpAddr[2] == 'T') && (lpAddr[3] == 'P') && (lpAddr[4] == ':')) { // This is IT!
lpAddr += 5; // point to the string
// Allocate string
if (FAILED(sc = MAPIAllocateMore((lstrlen(lpAddr) + 1) * sizeof(TCHAR), lpBase, (&lpSMTP)))) { DebugTrace("GetEMSSMTPAddress:MAPIAllocateMore -> %x\n", sc); hResult = ResultFromScode(sc); goto done; }
StrCpyN(lpSMTP, lpAddr, lstrlen(lpAddr) + 1); break; } } done: if (lpspv) { MAPIFreeBuffer(lpspv); } } return(lpSMTP); }
/***************************************************************************
Name : LoadWABEIDs
Purpose : Load the WAB's PAB create EIDs
Parameters: lpAdrBook -> lpAdrBook object lppContainer -> returned PAB container, caller must Release
Returns : HRESULT
Comment : Allocates global lpCreateEIDsWAB. Caller should WABFreeBuffer.
***************************************************************************/ HRESULT LoadWABEIDs(LPADRBOOK lpAdrBook, LPABCONT * lppContainer) { LPENTRYID lpWABEID = NULL; ULONG cbWABEID; HRESULT hResult; ULONG ulObjType; ULONG cProps;
if (hResult = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &cbWABEID, &lpWABEID)) { DebugTrace("WAB GetPAB -> %x\n", GetScode(hResult)); goto exit; } else { if (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, cbWABEID, // size of EntryID to open
lpWABEID, // EntryID to open
NULL, // interface
0, // flags
&ulObjType, (LPUNKNOWN *)lppContainer)) { DebugTrace("WAB OpenEntry(PAB) -> %x\n", GetScode(hResult)); goto exit; } }
// Get the WAB's creation entryids
if ((hResult = (*lppContainer)->lpVtbl->GetProps(*lppContainer, (LPSPropTagArray)&ptaCon, 0, &cProps, &lpCreateEIDsWAB))) { DebugTrace("Can't get container properties for WAB\n"); // Bad stuff here!
goto exit; }
// Validate the properites
if (lpCreateEIDsWAB[iconPR_DEF_CREATE_MAILUSER].ulPropTag != PR_DEF_CREATE_MAILUSER || lpCreateEIDsWAB[iconPR_DEF_CREATE_DL].ulPropTag != PR_DEF_CREATE_DL) { DebugTrace("WAB: Container property errors\n"); goto exit; }
exit: if (hResult) { if (lpCreateEIDsWAB) { WABFreeBuffer(lpCreateEIDsWAB); lpCreateEIDsWAB = NULL; } } if (lpWABEID) { WABFreeBuffer(lpWABEID); // bad object?
} return(hResult); }
/////////////////////////////////////////////////////////////////////////
// GetWABDllPath - loads the WAB DLL path from the registry
// szPath - ptr to buffer
// cb - sizeof buffer
//
void GetWABDllPath(LPTSTR szPath, ULONG cb) { DWORD dwType = 0; HKEY hKey = NULL; TCHAR szPathT[MAX_PATH]; ULONG cbData = sizeof(szPathT); if(szPath) { *szPath = '\0'; if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey)) { if(ERROR_SUCCESS == RegQueryValueEx( hKey, "", NULL, &dwType, (LPBYTE) szPathT, &cbData)) { if (dwType == REG_EXPAND_SZ) cbData = ExpandEnvironmentStrings(szPathT, szPath, cb / sizeof(TCHAR)); else { if(GetFileAttributes(szPathT) != 0xFFFFFFFF) StrCpyN(szPath, szPathT, cb); } } } } if(hKey) RegCloseKey(hKey); return; }
typedef HINSTANCE (STDAPICALLTYPE *PFNMLLOADLIBARY)(LPCTSTR lpLibFileName, HMODULE hModule, DWORD dwCrossCodePage);
static const TCHAR c_szShlwapiDll[] = TEXT("shlwapi.dll"); static const char c_szDllGetVersion[] = "DllGetVersion"; static const TCHAR c_szWABResourceDLL[] = TEXT("wab32res.dll"); static const TCHAR c_szWABDLL[] = TEXT("wab32.dll");
HINSTANCE LoadWABResourceDLL(HINSTANCE hInstWAB32) { TCHAR szPath[MAX_PATH]; HINSTANCE hinstShlwapi; PFNMLLOADLIBARY pfn; DLLGETVERSIONPROC pfnVersion; int iEnd; DLLVERSIONINFO info; HINSTANCE hInst = NULL;
hinstShlwapi = LoadLibrary(c_szShlwapiDll); if (hinstShlwapi != NULL) { pfnVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstShlwapi, c_szDllGetVersion); if (pfnVersion != NULL) { info.cbSize = sizeof(DLLVERSIONINFO); if (SUCCEEDED(pfnVersion(&info))) { if (info.dwMajorVersion >= 5) { #ifdef UNICODE
pfn = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)378); #else
pfn = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)377); #endif // UNICODE
if (pfn != NULL) hInst = pfn(c_szWABResourceDLL, hInstWAB32, 0); } } }
FreeLibrary(hinstShlwapi); }
if (NULL == hInst) { GetWABDllPath(szPath, sizeof(szPath)); iEnd = lstrlen(szPath); if (iEnd > lstrlen(c_szWABDLL)) { iEnd = iEnd - lstrlen(c_szWABDLL); StrCpyN(&szPath[iEnd], c_szWABResourceDLL, sizeof(szPath)/sizeof(TCHAR)-iEnd); hInst = LoadLibrary(szPath); } }
AssertSz(hInst, TEXT("Failed to LoadLibrary Lang Dll"));
return(hInst); }
/*
* DLL entry point for Win32 */ BOOL WINAPI DllEntryPoint(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved) {
switch ((short)dwReason) {
case DLL_PROCESS_ATTACH: hInstApp = hInstance; // set global DLL instance
hInst = LoadWABResourceDLL(hInstApp);
// We don't need these, so tell the OS to stop 'em
DisableThreadLibraryCalls(hInstApp); break;
case DLL_PROCESS_DETACH: if( hInst ) FreeLibrary(hInst); hInst = NULL;
break; }
return(TRUE); }
|