windows-nt/Source/XPSP1/NT/printscan/fax/exchange/ab/ootid.c

900 lines
29 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/***********************************************************************
*
* OOTID.C
*
* Microsoft At Work Fax Address Book OneOff Template ID object
* This file contains the code for implementing the Microsoft At Work Fax AB
* TID object.
*
* Copyright 1992, 1993 Microsoft Corporation. All Rights Reserved.
*
* Revision History:
*
* When Who What
* -------- ------------------ ---------------------------------------
* MAPI Original source from MAPI(154) sample AB Provider
* 3.7.94 Yoram Yaacovi Modifications to make it an At Work Fax ABP
* 4.2.94 Yoram Yaacovi Update to MAPI and sample AB 157
* 8.7.94 Yoram Yaacovi Update to MAPI and sample AB 304
* 8.24.94 Yoram Yaacovi Added OpenProperty and Release to support ddlbx and buttons in the one-off template
*
***********************************************************************/
#include "faxab.h"
/*
* External functions
*/
HRESULT
NewABUserButton(LPROOT, ULONG, ULONG, ULONG, LPMAPICONTROL FAR *);
void LoadIniParams(void);
/*
* OOTID jump table is defined here...
*/
static const OOTID_Vtbl vtblOOTID =
{
(OOTID_QueryInterface_METHOD *) ABU_QueryInterface,
(OOTID_AddRef_METHOD *) WRAP_AddRef,
OOTID_Release,
(OOTID_GetLastError_METHOD *) WRAP_GetLastError,
OOTID_SaveChanges,
(OOTID_GetProps_METHOD *) WRAP_GetProps,
(OOTID_GetPropList_METHOD *) WRAP_GetPropList,
OOTID_OpenProperty,
OOTID_SetProps,
(OOTID_DeleteProps_METHOD *) WRAP_DeleteProps,
(OOTID_CopyTo_METHOD *) WRAP_CopyTo,
(OOTID_CopyProps_METHOD *) WRAP_CopyProps,
(OOTID_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
(OOTID_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
};
// enum and property tag array for getting the properties
enum { ivalootidPR_COUNTRY_ID,
ivalootidPR_AREA_CODE,
ivalootidPR_TEL_NUMBER,
ivalootidPR_EMAIL_ADDRESS,
ivalootidPR_FAX_CP_NAME,
ivalootidMax };
static const SizedSPropTagArray(ivalootidMax,pta)=
{
ivalootidMax,
{
PR_COUNTRY_ID,
PR_AREA_CODE_A,
PR_TEL_NUMBER_A,
PR_EMAIL_ADDRESS_A,
PR_FAX_CP_NAME_A,
}
};
/*************************************************************************
*
- HrNewOOTID
-
* Creates the OOTID object associated with a mail user.
*
*
*/
HRESULT
HrNewOOTID( LPMAPIPROP * lppMAPIPropNew,
ULONG cbTemplateId,
LPENTRYID lpTemplateId,
ULONG ulTemplateFlags,
LPMAPIPROP lpPropData,
LPABLOGON lpABPLogon,
LPCIID lpInterface,
HINSTANCE hLibrary,
LPALLOCATEBUFFER lpAllocBuff,
LPALLOCATEMORE lpAllocMore,
LPFREEBUFFER lpFreeBuff,
LPMALLOC lpMalloc
)
{
LPOOTID lpOOTID;
SCODE sc;
HRESULT hResult = hrSuccess;
LPMAILUSER lpABOOUser = NULL;
ULONG ulObjType;
LPSPropValue lpspv=NULL;
ULONG ulcValues;
PARSEDTELNUMBER sParsedFaxAddr={{TEXT("")},{TEXT("")},{TEXT("")},{TEXT("")}};
/*
* Create the one-off object corresponding to the template id
*/
hResult = HrNewFaxOOUser( &lpABOOUser,
&ulObjType,
cbTemplateId,
lpTemplateId,
lpABPLogon,
lpInterface,
hLibrary,
lpAllocBuff,
lpAllocMore,
lpFreeBuff,
lpMalloc
);
if (HR_FAILED(hResult))
{
goto err;
}
/*
* Allocate space for the OOTID structure
*/
sc = lpAllocBuff(SIZEOF(OOTID), (LPVOID *) & lpOOTID);
if (FAILED(sc))
{
DebugTrace("NewOOTID() - AllocBuffer failed %s\n",SzDecodeScode(sc));
hResult = ResultFromScode (sc);
goto err;
}
/*
* Initialize the OOTID structure
*/
lpOOTID->lpVtbl = &vtblOOTID;
lpOOTID->lcInit = 1;
lpOOTID->hResult = hrSuccess;
lpOOTID->idsLastError = 0;
lpOOTID->hLibrary = hLibrary;
lpOOTID->lpAllocBuff = lpAllocBuff;
lpOOTID->lpAllocMore = lpAllocMore;
lpOOTID->lpFreeBuff = lpFreeBuff;
lpOOTID->lpMalloc = lpMalloc;
lpOOTID->lpABLogon = lpABPLogon;
lpOOTID->lpPropData = lpPropData;
lpOOTID->lpABUser = lpABOOUser;
lstrcpy(lpOOTID->szPreviousCPName, TEXT(""));
/*
* First time creation - must set the address type and template id.
*/
if (ulTemplateFlags==FILL_ENTRY)
{
ULONG ulCount;
LPSPropValue lpspv = NULL;
/*
* Copy all the properties from my object to the propdata
* These properties were set on the oouser object when it was created
* (by HrNewFaxOOUser calling into oouser.c)
*/
hResult = lpABOOUser->lpVtbl->GetProps( lpABOOUser,
NULL,
0, /* ansi */
&ulCount,
&lpspv
);
if (FAILED(hResult))
goto err;
hResult = lpPropData->lpVtbl->SetProps( lpPropData,
ulCount,
lpspv,
NULL
);
lpFreeBuff(lpspv);
if (FAILED(hResult))
goto err;
}
// entry already exists in the PAB
else
{
LPTSTR lpszCanonical=NULL;
/*
* Get the properties that make up the email address from the
* mapiprop object
*/
hResult = lpOOTID->lpPropData->lpVtbl->GetProps( lpOOTID->lpPropData,
(LPSPropTagArray) &pta,
0, /* ansi */
&ulcValues,
&lpspv
);
// see if the tel number component of the email address exists on the object
// if it doesn't, and there is a PR_EMAIL_ADDRESS,
// create the address components from the email address
if ( (PROP_TYPE(lpspv[ivalootidPR_TEL_NUMBER].ulPropTag) == PT_ERROR) &&
(PROP_TYPE(lpspv[ivalootidPR_EMAIL_ADDRESS].ulPropTag) != PT_ERROR)
)
{
#ifdef UNICODE
WCHAR szTmp[ MAX_PATH ];
CHAR szAnsiTelNumber[ 100 ];
CHAR szAnsiAreaCode[ 5 ];
szTmp[0] = 0;
MultiByteToWideChar( CP_ACP, 0, lpspv[ivalootidPR_EMAIL_ADDRESS].Value.lpszA, -1, szTmp, ARRAYSIZE(szTmp) );
DecodeFaxAddress(szTmp, &sParsedFaxAddr);
#else
DecodeFaxAddress(lpspv[ivalootidPR_EMAIL_ADDRESS].Value.LPSZ, &sParsedFaxAddr);
#endif
lpspv[ivalootidPR_TEL_NUMBER].ulPropTag = PR_TEL_NUMBER_A;
#ifdef UNICODE
szAnsiTelNumber[0] = 0;
WideCharToMultiByte( CP_ACP, 0, sParsedFaxAddr.szTelNumber, -1, szAnsiTelNumber, ARRAYSIZE(szAnsiTelNumber), NULL, NULL );
lpspv[ivalootidPR_TEL_NUMBER].Value.lpszA = szAnsiTelNumber;
#else
lpspv[ivalootidPR_TEL_NUMBER].Value.LPSZ = sParsedFaxAddr.szTelNumber;
#endif
lpspv[ivalootidPR_AREA_CODE].ulPropTag = PR_AREA_CODE_A;
#ifdef UNICODE
szAnsiAreaCode[0] = 0;
WideCharToMultiByte( CP_ACP, 0, sParsedFaxAddr.szAreaCode, -1, szAnsiAreaCode, ARRAYSIZE(szAnsiAreaCode), NULL, NULL );
lpspv[ivalootidPR_AREA_CODE].Value.lpszA = szAnsiAreaCode;
#else
lpspv[ivalootidPR_AREA_CODE].Value.LPSZ = sParsedFaxAddr.szAreaCode;
#endif
// CHECK: may need to get country id from country code
lpspv[ivalootidPR_COUNTRY_ID].ulPropTag = PR_COUNTRY_ID;
#ifdef UNICODE
lpspv[ivalootidPR_COUNTRY_ID].Value.l = (DWORD) wcstol(sParsedFaxAddr.szCountryCode,NULL,0);
#else
lpspv[ivalootidPR_COUNTRY_ID].Value.l = (DWORD) atol(sParsedFaxAddr.szCountryCode);
#endif
}
// save the starting (previous) cover page name, so that at SaveChanges time,
// I can see if the user changed it
if (PROP_TYPE(lpspv[ivalootidPR_FAX_CP_NAME].ulPropTag) != PT_ERROR)
{
#ifdef UNICODE
lpOOTID->szPreviousCPName[0] = 0;
MultiByteToWideChar( CP_ACP, 0, lpspv[ivalootidPR_FAX_CP_NAME].Value.lpszA, -1, lpOOTID->szPreviousCPName, ARRAYSIZE(lpOOTID->szPreviousCPName) );
#else
lstrcpy(lpOOTID->szPreviousCPName, lpspv[ivalootidPR_FAX_CP_NAME].Value.LPSZ);
#endif
}
/* free the buffer */
lpOOTID->lpFreeBuff(lpspv);
if (HR_FAILED(hResult))
{
DebugTrace("HrNewOOTID: SetProps failed %s\n",SzDecodeScode(GetScode(hResult)));
goto err;
}
}
/*
* AddRef lpPropData so we can use it after we return
*/
(void)lpPropData->lpVtbl->AddRef(lpPropData);
InitializeCriticalSection(&lpOOTID->cs);
*lppMAPIPropNew = (LPVOID) lpOOTID;
out:
DebugTraceResult(HrNewOOTID, hResult);
return hResult;
err:
if (lpABOOUser)
lpABOOUser->lpVtbl->Release(lpABOOUser);
lpFreeBuff(lpOOTID);
goto out;
}
/*********************************************************************
*********************************************************************
*
* The OOTID IMAPIProp methods
*
*/
STDMETHODIMP_(ULONG) OOTID_Release(LPOOTID lpOOTID)
{
LONG lcInit;
/*
* Check to see if it's large enough to hold this object
*/
if (IsBadReadPtr(lpOOTID, sizeof(OOTID)))
{
/*
* I'm not looking at an object that I expect to be.
*/
return 1;
}
/*
* Check to see that it's TIDs vtbl
*/
if (lpOOTID->lpVtbl != &vtblOOTID)
{
/*
* It's big enough but it's got the wrong vtbl.
*/
return 1;
}
/*
* Release the mapi property object
*/
lpOOTID->lpPropData->lpVtbl->Release( lpOOTID->lpPropData );
EnterCriticalSection(&lpOOTID->cs);
lcInit = --lpOOTID->lcInit;
LeaveCriticalSection(&lpOOTID->cs);
if (lcInit == 0)
{
/*
* Release the ABUser object
*/
lpOOTID->lpABUser->lpVtbl->Release( lpOOTID->lpABUser );
/*
* Clean up the critical section
*/
DeleteCriticalSection(&lpOOTID->cs);
/*
* Need to free the object
*/
lpOOTID->lpFreeBuff(lpOOTID);
return 0;
}
return lcInit;
}
/*****************************************************************************
SetProps
*****************************************************************************/
STDMETHODIMP
OOTID_SetProps( LPOOTID lpOOTID,
ULONG cValues,
LPSPropValue lpPropArray,
LPSPropProblemArray * lppProblems
)
{
enum { ivalspPR_DISPLAY_NAME = 0,
ivalspMax };
ULONG i;
SPropValue spv[ivalspMax];
HRESULT hResult=hrSuccess;
/* Validate the object */
if ( FBadUnknown(lpOOTID) ||
IsBadWritePtr(lpOOTID, SIZEOF(lpOOTID)) ||
IsBadReadPtr(lpOOTID->lpVtbl, offsetof(OOTID_Vtbl, SetProps)) ||
OOTID_SetProps != lpOOTID->lpVtbl->SetProps
)
{
DebugTrace("OOTID_SetProps -> E_INVALIDARG\n");
return ResultFromScode(E_INVALIDARG);
}
for (i=0; i < cValues; i++)
{
// see if one of the set properties is PR_FAX_CP_NAME_A
if (lpPropArray[i].ulPropTag == PR_FAX_CP_NAME_A)
{
// The cover page name is copied into the display name
spv[ivalspPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME_A;
spv[ivalspPR_DISPLAY_NAME].Value.lpszA = lpPropArray[i].Value.lpszA;
// set PR_DISPLAY_NAME
hResult = lpOOTID->lpPropData->lpVtbl->SetProps( lpOOTID->lpPropData,
ivalspMax,
spv,
NULL
);
if (HR_FAILED(hResult))
{
DebugTrace("OOTID_SetProps: SetProps on PR_DISPLAY_NAME failed %s\n",
SzDecodeScode(GetScode(hResult)));
goto out;
}
}
}
out:
// now set the properties I was asked to save
return hResult=lpOOTID->lpPropData->lpVtbl->SetProps( lpOOTID->lpPropData,
cValues,
lpPropArray,
lppProblems
);
}
/*
* These properties are used and set by the one off dialog.
* These properties combined make up a valid email address and display name
*/
// enum and property tag array for getting the properties
enum { ivalootidgPR_DISPLAY_NAME = 0,
ivalootidgPR_FAX_CP_NAME,
ivalootidgPR_COUNTRY_ID,
ivalootidgPR_AREA_CODE,
ivalootidgPR_TEL_NUMBER,
ivalootidgPR_GIVEN_NAME,
ivalootidgPR_SURNAME,
ivalootidgPR_EMAIL_ADDRESS,
ivalootidgMax };
static const SizedSPropTagArray(ivalootidgMax,ptag)=
{
ivalootidgMax,
{
PR_DISPLAY_NAME_A,
PR_FAX_CP_NAME_A,
PR_COUNTRY_ID,
PR_AREA_CODE_A,
PR_TEL_NUMBER_A,
PR_GIVEN_NAME_A,
PR_SURNAME_A,
PR_EMAIL_ADDRESS_A,
}
};
// enum for setting the created properties
enum { /*ivalootidsPR_DISPLAY_NAME = 0,
ivalootidsPR_FAX_CP_NAME,*/
ivalootidsPR_EMAIL_ADDRESS = 0,
ivalootidsPR_PRIMARY_FAX_NUMBER,
ivalootidsMax };
/*****************************************************************************
SaveChanges
*****************************************************************************/
STDMETHODIMP
OOTID_SaveChanges( LPOOTID lpOOTID,
ULONG ulFlags
)
{
HRESULT hResult;
LPSPropValue lpspv=NULL;
SPropValue spv[ivalootidsMax];
ULONG ulcValues;
BOOL bDispName=FALSE;
BOOL bFirstName=FALSE;
BOOL bSurName=FALSE;
BOOL bCPName=FALSE;
PARSEDTELNUMBER sParsedFaxAddr={{TEXT("")},{TEXT("")},{TEXT("")},{TEXT("")}};
ULONG dwCountryCode=0;
TCHAR szEncodedFaxAddress[CANONICAL_NUMBER_SIZE];
LPSTR lpszCanonical=NULL;
#ifdef UNICODE
CHAR szAnsiFaxAddr[CANONICAL_NUMBER_SIZE];
#endif
/*
* Check to see if it is big enough to be my object
*/
if (IsBadReadPtr(lpOOTID, SIZEOF(OOTID)))
{
/*
* Not big enough
*/
return MakeResult(E_INVALIDARG);
}
/*
* Check to see that it's OOTIDs vtbl
*/
if (lpOOTID->lpVtbl != &vtblOOTID)
{
/*
* vtbl not ours
*/
return MakeResult(E_INVALIDARG);
}
/*
* Get the properties that make up the email address from the
* mapiprop object
*/
hResult = lpOOTID->lpPropData->lpVtbl->GetProps( lpOOTID->lpPropData,
(LPSPropTagArray) &ptag,
0, /* ansi */
&ulcValues,
&lpspv
);
/*
* Abort in failure. Nothing to do without an email address
*/
if (FAILED(hResult))
{
DebugTrace("OOTID_SaveChanges: GetProps failed %s\n",SzDecodeScode(GetScode(hResult)));
goto err;
}
/***************************/
/****** display name *******/
/***************************/
/*
* Need to make the display name
* I believe there must be either a PR_DISPLAY_NAME or a PR_FAX_CP_NAME. If there isn't,
* I'll make one out of the first and last name
*/
#ifdef OLD_CODE
// Set the tags
spv[ivalootidsPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME_A;
spv[ivalootidsPR_FAX_CP_NAME].ulPropTag = PR_FAX_CP_NAME_A;
// Set the props to the exact value I got from GetProps
spv[ivalootidsPR_DISPLAY_NAME_A].Value.lpszA = lpspv[ivalootidgPR_DISPLAY_NAME].Value.lpszA;
spv[ivalootidsPR_FAX_CP_NAME_A].Value.lpszA = lpspv[ivalootidgPR_FAX_CP_NAME].Value.lpszA;
if ( (PROP_TYPE(lpspv[ivalootidgPR_DISPLAY_NAME_A].ulPropTag) != PT_ERROR) &&
lstrlenA(lpspv[ivalootidgPR_DISPLAY_NAME].Value.lpszA)
)
{
bDispName = TRUE;
}
if ( (PROP_TYPE(lpspv[ivalootidgPR_FAX_CP_NAME].ulPropTag) != PT_ERROR) &&
lstrlenA(lpspv[ivalootidgPR_FAX_CP_NAME].Value.lpszA))
{
bCPName = TRUE;
}
// Can't find PR_GIVEN_NAME anywhere in the MAPI or Mail world for now
if ( (PROP_TYPE(lpspv[ivalootidgPR_GIVEN_NAME].ulPropTag) != PT_ERROR) &&
lstrlenA(lpspv[ivalootidgPR_GIVEN_NAME].Value.lpszA))
{
bFirstName = TRUE;
}
if ( (PROP_TYPE(lpspv[ivalootidgPR_SURNAME].ulPropTag) != PT_ERROR) &&
lstrlenA(lpspv[ivalootidgPR_SURNAME].Value.lpszA))
{
bSurName = TRUE;
}
#ifdef EXTENDED_DEBUG
{
TCHAR msg[256];
wsprintf(msg, TEXT("Display name: %s\nCover page name: %s\nGiven name: %s\nSurname: %s\n"),
(bDispName ? lpspv[ivalootidgPR_DISPLAY_NAME].Value.LPSZ : TEXT("")),
(bCPName ? lpspv[ivalootidgPR_FAX_CP_NAME].Value.LPSZ : TEXT("")),
(bFirstName ? lpspv[ivalootidgPR_GIVEN_NAME].Value.LPSZ : TEXT("")),
(bSurName ? lpspv[ivalootidgPR_SURNAME].Value.LPSZ : TEXT("")));
MessageBox(HWND_DESKTOP, msg, TEXT("Debug Message"), MB_OK);
}
#endif
/*
The cases:
(1) No PR_DISPLAY_NAME, but there is PR_GIVEN_NAME or PR_SURNAME: this is the
creation of the entry, and the user entered first/last name in addition
to cover page name. Don't override PR_DISPLAY_NAME with PR_FAX_CP_NAME. Exchange
will use PR_GIVEN_NAME and PR_SURNAME to create PR_DISPLAY_NAME
(2) No PR_DISPLAY_NAME, and also PR_GIVEN_NAME or PR_SURNAME: this is the
creation of the entry, and the user did not enter first/last name.
Override PR_DISPLAY_NAME with PR_FAX_CP_NAME.
(3) There is a PR_DISPLAY_NAME, and the user has changed the PR_FAX_CP_NAME: this
is not a first time entry. The user selected to edit the template, and changed
the cover page name. We are assuming he wants to reflect these changes into
the display name. There were some CompuServe complaints on not doing this.
(4) There is a PR_DISPLAY_NAME, and the user did not change the PR_FAX_CP_NAME: this
is not a first time entry. The user selected to edit the template, but did not
change the cover page name. We are not overriding the display name in this
case, thus providing a way for the user to have a display name different from
the cover page name
*/
if (!bDispName)
{
if (bFirstName || bSurName)
// (1)
{
}
else
// (2)
{
// The cover page name is copied into the display name
spv[ivalootidsPR_DISPLAY_NAME].Value.lpszA =
lpspv[ivalootidgPR_FAX_CP_NAME].Value.lpszA;
}
}
else
{
#ifdef UNICODE
CHAR szAnsiPrevName[ MAX_PATH ];
szAnsiPrevName[0] = 0;
WideCharToMultiByte( CP_ACP, 0, lpOOTID->szPreviousName, -1, szAnsiPrevName, ARRAYSIZE(szAnsiPrevName), NULL, NULL );
if (lstrcmpA(lpspv[ivalootidgPR_FAX_CP_NAME_A].Value.lpszA, szAnsiPrevName))
#else
if (lstrcmp(lpspv[ivalootidgPR_FAX_CP_NAME_A].Value.lpszA, lpOOTID->szPreviousCPName))
#endif
// (3)
{
// The cover page name is copied into the display name
spv[ivalootidsPR_DISPLAY_NAME].Value.lpszA =
lpspv[ivalootidgPR_FAX_CP_NAME].Value.lpszA;
}
else
// (4)
{
}
}
#endif
/***************************/
/****** email address ******/
/***************************/
// Now do the email address
// initialize the email address prop value
spv[ivalootidsPR_EMAIL_ADDRESS].ulPropTag = PR_EMAIL_ADDRESS_A;
// if there is already an email address, and no fax number, this entry
// is not created from the UI (which requires a fax number)
// Generate the address components from the email address
if ( (PROP_TYPE(lpspv[ivalootidgPR_EMAIL_ADDRESS].ulPropTag) != PT_ERROR) &&
(lpspv[ivalootidgPR_EMAIL_ADDRESS].Value.lpszA) &&
(lstrlenA(lpspv[ivalootidgPR_EMAIL_ADDRESS].Value.lpszA)) &&
(PROP_TYPE(lpspv[ivalootidgPR_TEL_NUMBER].ulPropTag) == PT_ERROR)
)
{
spv[ivalootidsPR_EMAIL_ADDRESS].Value.lpszA =
lpspv[ivalootidgPR_EMAIL_ADDRESS].Value.lpszA;
}
// no email address. must compute from properties.
else
{
// Is there a fax number ?
if ( (PROP_TYPE(lpspv[ivalootidgPR_TEL_NUMBER].ulPropTag) != PT_ERROR) &&
(lpspv[ivalootidgPR_TEL_NUMBER].Value.lpszA) &&
(lstrlenA(lpspv[ivalootidgPR_TEL_NUMBER].Value.lpszA))
)
{
// truncate if necessary. note that the MAPI dialog should limit the user
// to this number of characters anyway
#ifdef UNICODE
sParsedFaxAddr.szTelNumber[0] = 0;
MultiByteToWideChar( CP_ACP, 0,
lpspv[ivalootidgPR_TEL_NUMBER].Value.lpszA, -1,
sParsedFaxAddr.szTelNumber,
ARRAYSIZE(sParsedFaxAddr.szTelNumber)
);
#else
lstrcpyn( sParsedFaxAddr.szTelNumber,
lpspv[ivalootidgPR_TEL_NUMBER].Value.lpszA,
ARRAYSIZE(sParsedFaxAddr.szTelNumber)
);
#endif
}
else
{
// must have at least a fax number
// this field is required in my MAPI dialog, so I should never get here
DebugTrace("OOTID_SaveChanges: No PR_FAX_NUMBER (or invalid) on the object\n");
goto err;
}
// Country Code
if (PROP_TYPE(lpspv[ivalootidgPR_COUNTRY_ID].ulPropTag) != PT_ERROR)
{
if (!GetCountryCode(lpspv[ivalootidgPR_COUNTRY_ID].Value.ul, &dwCountryCode))
{
// Use none
dwCountryCode = 0;
}
#ifdef UNICODE
{
CHAR szTemp[ARRAYSIZE(sParsedFaxAddr.szCountryCode)];
itoa(dwCountryCode, szTemp, COUNTRY_CODE_SIZE);
MultiByteToWideChar( CP_ACP, 0,
szTemp, -1,
sParsedFaxAddr.szCountryCode,
ARRAYSIZE(sParsedFaxAddr.szCountryCode)
);
}
#else
itoa(dwCountryCode, sParsedFaxAddr.szCountryCode, COUNTRY_CODE_SIZE);
#endif
}
// Area Code
if ( (PROP_TYPE(lpspv[ivalootidgPR_AREA_CODE].ulPropTag) != PT_ERROR) &&
(lpspv[ivalootidgPR_AREA_CODE].Value.lpszA)
)
{
// if we ended up with a 0 as the area code (error or internal extension,
// this won't be a canonical number and I don't need the area code.
// truncate if necessary
if (dwCountryCode != 0)
{
#ifdef UNICODE
sParsedFaxAddr.szAreaCode[0] = 0;
MultiByteToWideChar( CP_ACP, 0,
lpspv[ivalootidgPR_AREA_CODE].Value.lpszA,
-1,
sParsedFaxAddr.szAreaCode,
ARRAYSIZE(sParsedFaxAddr.szAreaCode)
);
#else
lstrcpyn( sParsedFaxAddr.szAreaCode,
lpspv[ivalootidgPR_AREA_CODE].Value.LPSZ,
ARRAYSIZE(sParsedFaxAddr.szAreaCode)
);
#endif
}
}
// Construct the canonical number from the components
EncodeFaxAddress(szEncodedFaxAddress, &sParsedFaxAddr);
#ifdef UNICODE
szAnsiFaxAddr[0] = 0;
WideCharToMultiByte( CP_ACP, 0, szEncodedFaxAddress, -1, szAnsiFaxAddr, ARRAYSIZE(szAnsiFaxAddr), NULL, NULL );
spv[ivalootidsPR_EMAIL_ADDRESS].Value.lpszA = szAnsiFaxAddr;
#else
spv[ivalootidsPR_EMAIL_ADDRESS].Value.LPSZ = szEncodedFaxAddress;
#endif
}
// now use the same fax number, but w/o the mailbox, to set the
// primary fax property on the telephone pane
spv[ivalootidsPR_PRIMARY_FAX_NUMBER].ulPropTag = PR_PRIMARY_FAX_NUMBER_A;
// don't want the mailbox for this
lpszCanonical = _mbsrchr(spv[ivalootidsPR_EMAIL_ADDRESS].Value.lpszA, '+');
if (lpszCanonical)
spv[ivalootidsPR_PRIMARY_FAX_NUMBER].Value.lpszA = lpszCanonical;
else
spv[ivalootidsPR_PRIMARY_FAX_NUMBER].Value.lpszA = "";
/***************************/
/****** toll list ******/
/***************************/
/* set the email address property value */
hResult= lpOOTID->lpPropData->lpVtbl->SetProps( lpOOTID->lpPropData,
ivalootidsMax,
spv,
NULL
);
if (HR_FAILED(hResult))
{
DebugTrace("OOTID_SaveChanges: SetProps failed %s\n",SzDecodeScode(GetScode(hResult)));
goto err;
}
hResult = lpOOTID->lpPropData->lpVtbl->SaveChanges( lpOOTID->lpPropData,
ulFlags
);
err:
/* free the buffer */
lpOOTID->lpFreeBuff(lpspv);
DebugTraceResult(OOTID_SaveChanges,hResult);
return hResult;
}
/*
- OOTID_OpenProperty
-
* This is needed to support the countries table and dial helper button on the one-off
* template. If the one-off template would only have edit controls nad checkboxes, I
* could call the wrapper object OpenProperty.
*
*/
STDMETHODIMP
OOTID_OpenProperty( LPOOTID lpOOTID,
ULONG ulPropTag,
LPCIID lpiid,
ULONG ulInterfaceOptions,
ULONG ulFlags,
LPUNKNOWN * lppUnk
)
{
HRESULT hResult;
/*
* Check to see if it's large enough to hold this object
*/
if (IsBadReadPtr(lpOOTID, SIZEOF(OOTID)))
{
/*
* No vtbl found
*/
return ResultFromScode(E_INVALIDARG);
}
/*
* Check to see that it's TIDs vtbl
*/
if (lpOOTID->lpVtbl != &vtblOOTID)
{
/*
* It's big enough but it's got the wrong vtbl.
*/
return ResultFromScode(E_INVALIDARG);
}
/*
* Don't want to check any other parameters here.
* Calls down to wrapped objects will do this for
* me.
*/
switch (ulPropTag)
{
// For now, I just call the underlying (my) user object method to handle, which
// means the template ID does not do anything.
case PR_DETAILS_TABLE:
case PR_DDLBX_COUNTRIES_TABLE:
case PR_DIAL_HELPER_BUTTON:
{
hResult = lpOOTID->lpABUser->lpVtbl->OpenProperty(
lpOOTID->lpABUser,
ulPropTag,
lpiid,
ulInterfaceOptions,
ulFlags,
lppUnk);
break;
}
default:
{
hResult = lpOOTID->lpPropData->lpVtbl->OpenProperty(
lpOOTID->lpPropData,
ulPropTag,
lpiid,
ulInterfaceOptions,
ulFlags,
lppUnk);
break;
}
}
DebugTraceResult(OOTID_OpenProperty, hResult);
return hResult;
}