Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

5087 lines
163 KiB

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