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.
1932 lines
60 KiB
1932 lines
60 KiB
#include "wabtest.h"
|
|
#include <assert.h>
|
|
|
|
#include "resource.h"
|
|
#include "..\luieng.dll\luieng.h"
|
|
|
|
extern LUIOUT LUIOut;
|
|
extern BOOL bLUIInit;
|
|
|
|
#ifdef WAB
|
|
extern LPWABOBJECT lpWABObject; //Global handle to session
|
|
#endif
|
|
|
|
#ifdef PAB
|
|
MAPIINIT_0 mapiinit = {
|
|
MAPI_INIT_VERSION,
|
|
MAPI_MULTITHREAD_NOTIFICATIONS
|
|
};
|
|
|
|
#endif //PAB
|
|
|
|
|
|
PropTableEntry PropTable[] = {
|
|
PR_7BIT_DISPLAY_NAME, "PR_7BIT_DISPLAY_NAME", 0,
|
|
PR_ACCOUNT, "PR_ACCOUNT", 0,
|
|
PR_ADDRTYPE, "PR_ADDRTYPE", 0,
|
|
PR_ALTERNATE_RECIPIENT, "PR_ALTERNATE_RECIPIENT", 0,
|
|
PR_ASSISTANT, "PR_ASSISTANT", 0,
|
|
PR_ASSISTANT_TELEPHONE_NUMBER, "PR_ASSISTANT_TELEPHONE_NUMBER", 0,
|
|
PR_BEEPER_TELEPHONE_NUMBER, "PR_BEEPER_TELEPHONE_NUMBER", 0,
|
|
PR_BIRTHDAY, "PR_BIRTHDAY", 0,
|
|
PR_BUSINESS_ADDRESS_CITY, "PR_BUSINESS_ADDRESS_CITY", 0,
|
|
PR_BUSINESS_ADDRESS_COUNTRY, "PR_BUSINESS_ADDRESS_COUNTRY", 0,
|
|
PR_BUSINESS_ADDRESS_POST_OFFICE_BOX, "PR_BUSINESS_ADDRESS_POST_OFFICE_BOX", 0,
|
|
PR_BUSINESS_ADDRESS_POSTAL_CODE, "PR_BUSINESS_ADDRESS_POSTAL_CODE", 0,
|
|
PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE, "PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE", 0,
|
|
PR_BUSINESS_ADDRESS_STREET, "PR_BUSINESS_ADDRESS_STREET", 0,
|
|
PR_BUSINESS_FAX_NUMBER, "PR_BUSINESS_FAX_NUMBER", 0,
|
|
PR_BUSINESS_HOME_PAGE, "PR_BUSINESS_HOME_PAGE", 0,
|
|
PR_BUSINESS_TELEPHONE_NUMBER, "PR_BUSINESS_TELEPHONE_NUMBER", 0,
|
|
PR_BUSINESS2_TELEPHONE_NUMBER, "PR_BUSINESS2_TELEPHONE_NUMBER", 0,
|
|
PR_CALLBACK_TELEPHONE_NUMBER, "PR_CALLBACK_TELEPHONE_NUMBER", 0,
|
|
PR_CAR_TELEPHONE_NUMBER, "PR_CAR_TELEPHONE_NUMBER", 0,
|
|
PR_CELLULAR_TELEPHONE_NUMBER, "PR_CELLULAR_TELEPHONE_NUMBER", 0,
|
|
PR_CHILDRENS_NAMES, "PR_CHILDRENS_NAMES", 0,
|
|
PR_COMMENT, "PR_COMMENT", 0,
|
|
PR_COMPANY_MAIN_PHONE_NUMBER, "PR_COMPANY_MAIN_PHONE_NUMBER", 0,
|
|
PR_COMPANY_NAME, "PR_COMPANY_NAME", 0,
|
|
PR_COMPUTER_NETWORK_NAME, "PR_COMPUTER_NETWORK_NAME", 0,
|
|
PR_CONTACT_ADDRTYPES, "PR_CONTACT_ADDRTYPES", 0,
|
|
PR_CONTACT_DEFAULT_ADDRESS_INDEX, "PR_CONTACT_DEFAULT_ADDRESS_INDEX", 0,
|
|
PR_CONTACT_EMAIL_ADDRESSES, "PR_CONTACT_EMAIL_ADDRESSES", 0,
|
|
PR_CONTACT_ENTRYIDS, "PR_CONTACT_ENTRYIDS", 0,
|
|
PR_CONTACT_VERSION, "PR_CONTACT_VERSION", 0,
|
|
PR_CONVERSION_PROHIBITED, "PR_CONVERSION_PROHIBITED", 0,
|
|
PR_COUNTRY, "PR_COUNTRY", 0,
|
|
PR_CUSTOMER_ID, "PR_CUSTOMER_ID", 0,
|
|
PR_DEPARTMENT_NAME, "PR_DEPARTMENT_NAME", 0,
|
|
PR_DISCLOSE_RECIPIENTS, "PR_DISCLOSE_RECIPIENTS", 0,
|
|
PR_DISPLAY_NAME, "PR_DISPLAY_NAME", 0,
|
|
PR_DISPLAY_NAME_PREFIX, "PR_DISPLAY_NAME_PREFIX", 0,
|
|
PR_EMAIL_ADDRESS, "PR_EMAIL_ADDRESS", 0,
|
|
PR_ENTRYID, "PR_ENTRYID", 0,
|
|
PR_FTP_SITE, "PR_FTP_SITE", 0,
|
|
PR_GENDER, "PR_GENDER", 0,
|
|
PR_GENERATION, "PR_GENERATION", 0,
|
|
PR_GIVEN_NAME, "PR_GIVEN_NAME", 0,
|
|
PR_GOVERNMENT_ID_NUMBER, "PR_GOVERNMENT_ID_NUMBER", 0,
|
|
PR_HOBBIES, "PR_HOBBIES", 0,
|
|
PR_HOME_ADDRESS_CITY, "PR_HOME_ADDRESS_CITY", 0,
|
|
PR_HOME_ADDRESS_COUNTRY, "PR_HOME_ADDRESS_COUNTRY", 0,
|
|
PR_HOME_ADDRESS_POST_OFFICE_BOX, "PR_HOME_ADDRESS_POST_OFFICE_BOX", 0,
|
|
PR_HOME_ADDRESS_POSTAL_CODE, "PR_HOME_ADDRESS_POSTAL_CODE", 0,
|
|
PR_HOME_ADDRESS_STATE_OR_PROVINCE, "PR_HOME_ADDRESS_STATE_OR_PROVINCE", 0,
|
|
PR_HOME_ADDRESS_STREET, "PR_HOME_ADDRESS_STREET", 0,
|
|
PR_HOME_FAX_NUMBER, "PR_HOME_FAX_NUMBER", 0,
|
|
PR_HOME_TELEPHONE_NUMBER, "PR_HOME_TELEPHONE_NUMBER", 0,
|
|
PR_HOME2_TELEPHONE_NUMBER, "PR_HOME2_TELEPHONE_NUMBER", 0,
|
|
PR_INITIALS, "PR_INITIALS", 0,
|
|
PR_ISDN_NUMBER, "PR_ISDN_NUMBER", 0,
|
|
PR_KEYWORD, "PR_KEYWORD", 0,
|
|
PR_LANGUAGE, "PR_LANGUAGE", 0,
|
|
PR_LOCALITY, "PR_LOCALITY", 0,
|
|
PR_LOCATION, "PR_LOCATION", 0,
|
|
PR_MAIL_PERMISSION, "PR_MAIL_PERMISSION", 0,
|
|
PR_MANAGER_NAME, "PR_MANAGER_NAME", 0,
|
|
PR_MHS_COMMON_NAME, "PR_MHS_COMMON_NAME", 0,
|
|
PR_MIDDLE_NAME, "PR_MIDDLE_NAME", 0,
|
|
PR_MOBILE_TELEPHONE_NUMBER, "PR_MOBILE_TELEPHONE_NUMBER", 0,
|
|
PR_NICKNAME, "PR_NICKNAME", 0,
|
|
PR_OBJECT_TYPE, "PR_OBJECT_TYPE", 0,
|
|
PR_OFFICE_LOCATION, "PR_OFFICE_LOCATION", 0,
|
|
PR_OFFICE_TELEPHONE_NUMBER, "PR_OFFICE_TELEPHONE_NUMBER", 0,
|
|
PR_OFFICE2_TELEPHONE_NUMBER, "PR_OFFICE2_TELEPHONE_NUMBER", 0,
|
|
PR_ORGANIZATIONAL_ID_NUMBER, "PR_ORGANIZATIONAL_ID_NUMBER", 0,
|
|
PR_ORIGINAL_DISPLAY_NAME, "PR_ORIGINAL_DISPLAY_NAME", 0,
|
|
PR_ORIGINAL_ENTRYID, "PR_ORIGINAL_ENTRYID", 0,
|
|
PR_ORIGINAL_SEARCH_KEY, "PR_ORIGINAL_SEARCH_KEY", 0,
|
|
PR_OTHER_ADDRESS_CITY, "PR_OTHER_ADDRESS_CITY", 0,
|
|
PR_OTHER_ADDRESS_COUNTRY, "PR_OTHER_ADDRESS_COUNTRY", 0,
|
|
PR_OTHER_ADDRESS_POST_OFFICE_BOX, "PR_OTHER_ADDRESS_POST_OFFICE_BOX", 0,
|
|
PR_OTHER_ADDRESS_POSTAL_CODE, "PR_OTHER_ADDRESS_POSTAL_CODE", 0,
|
|
PR_OTHER_ADDRESS_STATE_OR_PROVINCE, "PR_OTHER_ADDRESS_STATE_OR_PROVINCE", 0,
|
|
PR_OTHER_ADDRESS_STREET,"PR_OTHER_ADDRESS_STREET", 0,
|
|
PR_OTHER_TELEPHONE_NUMBER, "PR_OTHER_TELEPHONE_NUMBER", 0,
|
|
PR_PAGER_TELEPHONE_NUMBER, "PR_PAGER_TELEPHONE_NUMBER", 0,
|
|
PR_PERSONAL_HOME_PAGE, "PR_PERSONAL_HOME_PAGE", 0,
|
|
PR_POST_OFFICE_BOX, "PR_POST_OFFICE_BOX", 0,
|
|
PR_POSTAL_ADDRESS, "PR_POSTAL_ADDRESS", 0,
|
|
PR_POSTAL_CODE, "PR_POSTAL_CODE", 0,
|
|
PR_PREFERRED_BY_NAME, "PR_PREFERRED_BY_NAME", 0,
|
|
PR_PRIMARY_FAX_NUMBER, "PR_PRIMARY_FAX_NUMBER", 0,
|
|
PR_PRIMARY_TELEPHONE_NUMBER, "PR_PRIMARY_TELEPHONE_NUMBER", 0,
|
|
PR_PROFESSION, "PR_PROFESSION", 0,
|
|
PR_RADIO_TELEPHONE_NUMBER, "PR_RADIO_TELEPHONE_NUMBER", 0,
|
|
PR_SEND_RICH_INFO, "PR_SEND_RICH_INFO", 0,
|
|
PR_SPOUSE_NAME, "PR_SPOUSE_NAME", 0,
|
|
PR_STATE_OR_PROVINCE, "PR_STATE_OR_PROVINCE", 0,
|
|
PR_STREET_ADDRESS, "PR_STREET_ADDRESS", 0,
|
|
PR_SURNAME, "PR_SURNAME", 0,
|
|
PR_TELEX_NUMBER, "PR_TELEX_NUMBER", 0,
|
|
PR_TITLE, "PR_TITLE", 0,
|
|
PR_TRANSMITABLE_DISPLAY_NAME, "PR_TRANSMITABLE_DISPLAY_NAME", 0,
|
|
PR_TTYTDD_PHONE_NUMBER, "PR_TTYTDD_PHONE_NUMBER", 0,
|
|
PR_USER_CERTIFICATE, "PR_USER_CERTIFICATE", 0,
|
|
PR_WEDDING_ANNIVERSARY, "PR_WEDDING_ANNIVERSARY", 0,
|
|
PR_USER_X509_CERTIFICATE, "PR_USER_X509_CERTIFICATE", 0,
|
|
|
|
(ULONG)0, "End of Table", 0
|
|
};
|
|
|
|
|
|
|
|
HRESULT OpenPABID( IN LPADRBOOK lpAdrBook,
|
|
OUT ULONG *lpcbEidPAB,
|
|
OUT LPENTRYID *lppEidPAB,
|
|
OUT LPABCONT *lppPABCont,
|
|
OUT ULONG *lpulObjType)
|
|
{
|
|
HRESULT hr = hrSuccess;
|
|
int retval = TRUE;
|
|
|
|
*lpulObjType = 0;
|
|
|
|
if ( (NULL == lpcbEidPAB) ||
|
|
(NULL == lppEidPAB) ||
|
|
(NULL == lppPABCont) )
|
|
return(FALSE);
|
|
|
|
*lpcbEidPAB = 0;
|
|
*lppEidPAB = NULL;
|
|
*lppPABCont = NULL;
|
|
|
|
|
|
//
|
|
// Get the PAB
|
|
//
|
|
hr = lpAdrBook->GetPAB(
|
|
OUT lpcbEidPAB,
|
|
OUT lppEidPAB);
|
|
|
|
if (HR_FAILED(hr)) {
|
|
retval = FALSE;
|
|
goto out;
|
|
}
|
|
|
|
if (0 == *lpcbEidPAB) //There is no PAB associated with this profile
|
|
{
|
|
LUIOut(L2, "Call to GetPAB FAILED. No PAB associated with this profile");
|
|
retval = FALSE;
|
|
goto out;
|
|
}
|
|
|
|
|
|
//
|
|
// Open the PAB Container
|
|
//
|
|
hr = lpAdrBook->OpenEntry(
|
|
IN *lpcbEidPAB,
|
|
IN *lppEidPAB,
|
|
IN NULL, //interface
|
|
IN MAPI_MODIFY, //flags
|
|
OUT lpulObjType,
|
|
OUT (LPUNKNOWN *) lppPABCont);
|
|
|
|
if (0 == *lpulObjType) {
|
|
retval = FALSE;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
return(retval);
|
|
}
|
|
|
|
|
|
#ifdef PAB
|
|
BOOL MapiInitLogon(OUT LPMAPISESSION * lppMAPISession)
|
|
{
|
|
|
|
HRESULT hr = hrSuccess;
|
|
SCODE sc = SUCCESS_SUCCESS;
|
|
int retval=TRUE;
|
|
char szProfileName[SML_BUF];
|
|
|
|
hr = MAPIInitialize(IN & mapiinit);
|
|
|
|
|
|
if (hr)
|
|
{
|
|
if (FAILED (GetScode(hr))) {
|
|
LUIOut(L1,"Could not initialize MAPI\n");
|
|
retval=FALSE;
|
|
}
|
|
}
|
|
|
|
szProfileName[0]='\0';
|
|
GetPrivateProfileString("Misc","Profile","",szProfileName,SML_BUF,"c:\\pabtests.ini");
|
|
|
|
sc = MAPILogonEx(
|
|
IN 0, //window handle
|
|
IN szProfileName, //Profile Name
|
|
IN NULL, //Password
|
|
IN MAPI_NEW_SESSION |
|
|
MAPI_EXTENDED |
|
|
MAPI_LOGON_UI |
|
|
MAPI_EXPLICIT_PROFILE |
|
|
MAPI_ALLOW_OTHERS |
|
|
MAPI_NO_MAIL, //Flags
|
|
OUT lppMAPISession); //Session Pointer address
|
|
|
|
if (FAILED(sc))
|
|
{
|
|
hr = ResultFromScode(sc);
|
|
LUIOut(L1,"Could not start MAPI Session");
|
|
retval=FALSE;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
#endif //PAB
|
|
|
|
BOOL GetPropsFromIniBufEntry(LPSTR EntryBuf,ULONG cValues, char (*EntProp)[BIG_BUF])
|
|
{
|
|
//char szTemp[BIG_BUF];
|
|
int j=0;
|
|
if (EntryBuf) {
|
|
for (int i = 0; i < (int)cValues; i++) {
|
|
if ((*EntryBuf) == '"') {
|
|
EntryBuf++;
|
|
}
|
|
j=0;
|
|
while ((*EntryBuf)&&((*EntryBuf) != '"')&&(j< BIG_BUF-1)) {
|
|
|
|
EntProp[i][j]= *EntryBuf;
|
|
j++; EntryBuf++;
|
|
}
|
|
EntProp[i][j]='\0';
|
|
if (*EntryBuf) EntryBuf++;
|
|
if ((*EntryBuf)&&((*EntryBuf) == ',')) EntryBuf++;
|
|
}
|
|
return TRUE;
|
|
}
|
|
else {
|
|
for (int i = 0; i < (int)cValues; i++) {
|
|
EntProp[i][0]=0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT HrCreateEntryListFromID(
|
|
IN LPWABOBJECT lpLocalWABObject,
|
|
IN ULONG cbeid, // count of bytes in Entry ID
|
|
IN LPENTRYID lpeid, // pointer to Entry ID
|
|
OUT LPENTRYLIST FAR *lppEntryList) // pointer to address variable of Entry
|
|
// list
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
SCODE sc = 0;
|
|
LPVOID lpvSBinaryArray = NULL;
|
|
LPVOID lpvSBinary = NULL;
|
|
LPVOID lpv = NULL;
|
|
|
|
|
|
if (NULL == lppEntryList) return(FALSE);
|
|
|
|
*lppEntryList = NULL;
|
|
|
|
|
|
#ifdef PAB
|
|
sc = MAPIAllocateBuffer(cbeid, &lpv);
|
|
#endif
|
|
#ifdef WAB
|
|
sc = lpLocalWABObject->AllocateBuffer(cbeid, &lpv);
|
|
#endif
|
|
|
|
|
|
if(FAILED(sc))
|
|
{
|
|
hr = ResultFromScode(sc);
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
// Copy entry ID
|
|
CopyMemory(lpv, lpeid, cbeid);
|
|
|
|
|
|
#ifdef PAB
|
|
sc = MAPIAllocateBuffer(sizeof(SBinary), &lpvSBinary);
|
|
#endif
|
|
#ifdef WAB
|
|
sc = lpLocalWABObject->AllocateBuffer(sizeof(SBinary), &lpvSBinary);
|
|
#endif
|
|
|
|
if(FAILED(sc))
|
|
{
|
|
hr = ResultFromScode(sc);
|
|
goto cleanup;
|
|
}
|
|
|
|
// Initialize SBinary structure
|
|
ZeroMemory(lpvSBinary, sizeof(SBinary));
|
|
|
|
((LPSBinary)lpvSBinary)->cb = cbeid;
|
|
((LPSBinary)lpvSBinary)->lpb = (LPBYTE)lpv;
|
|
|
|
#ifdef PAB
|
|
sc = MAPIAllocateBuffer(sizeof(SBinaryArray), &lpvSBinaryArray);
|
|
#endif
|
|
#ifdef WAB
|
|
sc = lpLocalWABObject->AllocateBuffer(sizeof(SBinaryArray), &lpvSBinaryArray);
|
|
#endif
|
|
|
|
if(FAILED(sc))
|
|
{
|
|
hr = ResultFromScode(sc);
|
|
goto cleanup;
|
|
}
|
|
|
|
// Initialize SBinaryArray structure
|
|
ZeroMemory(lpvSBinaryArray, sizeof(SBinaryArray));
|
|
|
|
((SBinaryArray *)lpvSBinaryArray)->cValues = 1;
|
|
((SBinaryArray *)lpvSBinaryArray)->lpbin = (LPSBinary)lpvSBinary;
|
|
|
|
*lppEntryList = (LPENTRYLIST)lpvSBinaryArray;
|
|
|
|
cleanup:
|
|
|
|
if (HR_FAILED(hr))
|
|
{
|
|
#ifdef PAB
|
|
if (lpv)
|
|
MAPIFreeBuffer(lpv);
|
|
|
|
if (lpvSBinary)
|
|
MAPIFreeBuffer(lpvSBinary);
|
|
|
|
if (lpvSBinaryArray)
|
|
MAPIFreeBuffer(lpvSBinaryArray);
|
|
#endif
|
|
#ifdef WAB
|
|
if (lpv)
|
|
lpLocalWABObject->FreeBuffer(lpv);
|
|
|
|
if (lpvSBinary)
|
|
lpLocalWABObject->FreeBuffer(lpvSBinary);
|
|
|
|
if (lpvSBinaryArray)
|
|
lpLocalWABObject->FreeBuffer(lpvSBinaryArray);
|
|
#endif
|
|
}
|
|
|
|
return(hr);
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT HrCreateEntryListFromRows(
|
|
IN LPWABOBJECT lpLocalWABObject,
|
|
IN LPSRowSet far* lppRows,
|
|
OUT LPENTRYLIST FAR *lppEntryList) // pointer to address variable of Entry
|
|
// list
|
|
{ LPSRowSet lpRows = *lppRows;
|
|
HRESULT hr = NOERROR;
|
|
SCODE sc = 0;
|
|
SBinaryArray* lpvSBinaryArray = NULL;
|
|
ULONG Rows = lpRows->cRows;
|
|
unsigned int PropIndex;
|
|
ULONG cb;
|
|
LPENTRYID lpb;
|
|
|
|
|
|
|
|
if (NULL == lppEntryList) return(FALSE);
|
|
|
|
*lppEntryList = NULL;
|
|
if (lpRows) {
|
|
// Allocate the SBinaryArray
|
|
sc = lpLocalWABObject->AllocateBuffer(sizeof(SBinaryArray), (void**)&lpvSBinaryArray);
|
|
if(FAILED(sc))
|
|
{
|
|
LUIOut(L2, "HrCreateEntryListFromRows: Unable to allocate memory for the SBinaryArray.");
|
|
hr = ResultFromScode(sc);
|
|
goto cleanup;
|
|
}
|
|
// Initialize SBinaryArray structure
|
|
ZeroMemory(lpvSBinaryArray, sizeof(SBinaryArray));
|
|
lpvSBinaryArray->cValues = Rows;
|
|
|
|
// Allocate the SBinary structures
|
|
sc = lpLocalWABObject->AllocateBuffer((Rows*sizeof(SBinary)), (void**)&lpvSBinaryArray->lpbin);
|
|
if(FAILED(sc))
|
|
{
|
|
LUIOut(L2, "HrCreateEntryListFromRows: Unable to allocate memory for the SBinary structures.");
|
|
hr = ResultFromScode(sc);
|
|
goto cleanup;
|
|
}
|
|
// Initialize SBinary structure
|
|
ZeroMemory(lpvSBinaryArray->lpbin, (Rows*sizeof(SBinary)));
|
|
FindPropinRow(&lpRows->aRow[0], // Find which column has the EID
|
|
PR_ENTRYID,
|
|
&PropIndex);
|
|
|
|
// Walk through the rows, allocate the lpb and copy over each cbeid and lpb into the entrylist
|
|
for (ULONG Row = 0; Row < Rows; Row++) {
|
|
cb = lpRows->aRow[Row].lpProps[PropIndex].Value.bin.cb,
|
|
lpb = (ENTRYID*)lpRows->aRow[Row].lpProps[PropIndex].Value.bin.lpb,
|
|
sc = lpLocalWABObject->AllocateBuffer(cb, (void**)&(lpvSBinaryArray->lpbin[Row].lpb));
|
|
if(FAILED(sc))
|
|
{
|
|
LUIOut(L2, "HrCreateEntryListFromRows: Unable to allocate memory for the SBinary->lpb.");
|
|
hr = ResultFromScode(sc);
|
|
goto cleanup;
|
|
}
|
|
// Copy entry ID
|
|
lpvSBinaryArray->lpbin[Row].cb = cb;
|
|
CopyMemory(lpvSBinaryArray->lpbin[Row].lpb, lpb, cb);
|
|
}
|
|
*lppEntryList = (LPENTRYLIST)lpvSBinaryArray;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
|
|
cleanup:
|
|
|
|
if (HR_FAILED(hr))
|
|
{
|
|
for (ULONG Kill=0; Kill<Rows; Kill++) {
|
|
if (lpvSBinaryArray->lpbin[Kill].lpb)
|
|
lpLocalWABObject->FreeBuffer(lpvSBinaryArray->lpbin[Kill].lpb);
|
|
lpvSBinaryArray->lpbin[Kill].lpb = NULL;
|
|
}
|
|
|
|
if (lpvSBinaryArray->lpbin)
|
|
lpLocalWABObject->FreeBuffer(lpvSBinaryArray->lpbin);
|
|
|
|
if (lpvSBinaryArray)
|
|
lpLocalWABObject->FreeBuffer(lpvSBinaryArray);
|
|
}
|
|
|
|
return(hr);
|
|
|
|
}
|
|
|
|
|
|
BOOL FreeEntryList(IN LPWABOBJECT lpLocalWABObject,
|
|
IN LPENTRYLIST *lppEntryList) // pointer to address variable of Entry
|
|
// list
|
|
{ LPENTRYLIST lpEntryList = *lppEntryList;
|
|
|
|
if (lpEntryList == NULL) return FALSE;
|
|
for (ULONG Row = 0; Row < lpEntryList->cValues; Row++) {
|
|
if (lpEntryList->lpbin[Row].lpb)
|
|
lpLocalWABObject->FreeBuffer(lpEntryList->lpbin[Row].lpb);
|
|
}
|
|
|
|
if (lpEntryList->lpbin)
|
|
lpLocalWABObject->FreeBuffer(lpEntryList->lpbin);
|
|
|
|
if (lpEntryList)
|
|
lpLocalWABObject->FreeBuffer(lpEntryList);
|
|
|
|
*lppEntryList = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL FreeRows(IN LPWABOBJECT lpLocalWABObject,
|
|
IN LPSRowSet far* lppRows)
|
|
{ LPSRowSet lpRows = *lppRows;
|
|
|
|
#ifdef WAB
|
|
if (lpRows) {
|
|
for (ULONG Kill = 0; Kill < lpRows->cRows; Kill++)
|
|
lpLocalWABObject->FreeBuffer(lpRows->aRow[Kill].lpProps);
|
|
lpLocalWABObject->FreeBuffer(lpRows);
|
|
*lppRows = NULL;
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL DisplayRows(IN LPSRowSet lpRows)
|
|
{ ULONG Rows, Columns;
|
|
WORD* Key;
|
|
if (lpRows) {
|
|
Rows = lpRows->cRows;
|
|
LUIOut(L2, "%u rows found.", Rows);
|
|
for (ULONG Row = 0; Row < Rows; Row++) {
|
|
Columns = lpRows->aRow[Row].cValues;
|
|
LUIOut(L3, "Row %u contains %u columns.", Row, Columns);
|
|
for (ULONG Column = 0; Column < Columns; Column++) {
|
|
switch(lpRows->aRow[Row].lpProps[Column].ulPropTag) {
|
|
case PR_ADDRTYPE:
|
|
LUIOut(L3, "Column %u: PR_ADDRTYPE = %s", Column, lpRows->aRow[Row].lpProps[Column].Value.LPSZ);
|
|
break;
|
|
case PR_DISPLAY_NAME:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_NAME = %s", Column, lpRows->aRow[Row].lpProps[Column].Value.LPSZ);
|
|
break;
|
|
case PR_DISPLAY_TYPE:
|
|
switch(lpRows->aRow[Row].lpProps[Column].Value.l) {
|
|
case DT_AGENT:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_AGENT", Column);
|
|
break;
|
|
case DT_DISTLIST:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_DISTLIST", Column);
|
|
break;
|
|
case DT_FORUM:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_FORUM", Column);
|
|
break;
|
|
case DT_MAILUSER:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_MAILUSER", Column);
|
|
break;
|
|
case DT_ORGANIZATION:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_ORGANIZATION", Column);
|
|
break;
|
|
case DT_PRIVATE_DISTLIST:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_PRIVATE_DISTLIST", Column);
|
|
break;
|
|
case DT_REMOTE_MAILUSER:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = DT_REMOTE_MAILUSER", Column);
|
|
break;
|
|
default:
|
|
LUIOut(L3, "Column %u: PR_DISPLAY_TYPE = UNKNOWN!! [0x%x]", Column,
|
|
lpRows->aRow[Row].lpProps[Column].Value.l);
|
|
}
|
|
break;
|
|
case PR_ENTRYID:
|
|
LUIOut(L3, "Column %u: PR_ENTRYID", Column);
|
|
break;
|
|
case PR_INSTANCE_KEY:
|
|
Key = (WORD*)lpRows->aRow[Row].lpProps[Column].Value.bin.lpb;
|
|
LUIOut(L3, "Column %u: PR_INSTANCE_KEY = 0x%x%x%x%x%x%x%x%x", Column,
|
|
Key[0],Key[2],Key[4],Key[6],Key[8],Key[10],Key[12],Key[14]);
|
|
break;
|
|
case PR_OBJECT_TYPE:
|
|
switch(lpRows->aRow[Row].lpProps[Column].Value.l) {
|
|
case MAPI_ABCONT:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_ABCONT", Column);
|
|
break;
|
|
case MAPI_ADDRBOOK:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_ADDRBOOK", Column);
|
|
break;
|
|
case MAPI_ATTACH:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_ATTACH", Column);
|
|
break;
|
|
case MAPI_DISTLIST:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_DISTLIST", Column);
|
|
break;
|
|
case MAPI_FOLDER:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_FOLDER", Column);
|
|
break;
|
|
case MAPI_FORMINFO:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_FORMINFO", Column);
|
|
break;
|
|
case MAPI_MAILUSER:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_MAILUSER", Column);
|
|
break;
|
|
case MAPI_MESSAGE:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_MESSAGE", Column);
|
|
break;
|
|
case MAPI_PROFSECT:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_PROFSECT", Column);
|
|
break;
|
|
case MAPI_STATUS:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_STATUS", Column);
|
|
break;
|
|
case MAPI_STORE:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = MAPI_STORE", Column);
|
|
break;
|
|
default:
|
|
LUIOut(L3, "Column %u: PR_OBJECT_TYPE = UNKNOWN!! [0x%x]", Column,
|
|
lpRows->aRow[Row].lpProps[Column].Value.l);
|
|
}
|
|
break;
|
|
case PR_RECORD_KEY:
|
|
LUIOut(L3, "Column %u: PR_RECORD_KEY", Column);
|
|
break;
|
|
default:
|
|
LUIOut(L3, "Column %u: Property tag UNKNOWN!! [0x%x]", Column,
|
|
lpRows->aRow[Row].lpProps[Column].ulPropTag);
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
BOOL ValidateAdrList(LPADRLIST lpAdrList, ULONG cEntries)
|
|
{
|
|
int i = 0;
|
|
int idx = 0;
|
|
int cMaxProps = 0;
|
|
|
|
for(i=0; i<(int) cEntries; ++i)
|
|
{
|
|
cMaxProps = (int)lpAdrList->aEntries[i].cValues;
|
|
//Check to see if Email Address Type exists
|
|
idx=0;
|
|
while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ADDRTYPE )
|
|
{
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_ADDRTYPE was not found in the lpAdrList");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//Check to see if Email Address exists
|
|
idx=0;
|
|
while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_OBJECT_TYPE )
|
|
{
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_OBJECT_TYPE was not found in the lpAdrList");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//Check to see if Email Address exists
|
|
idx=0;
|
|
while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_TYPE )
|
|
{
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_DISPLAY_TYPE was not found in the lpAdrList");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//Check to see if Display Name exists
|
|
idx=0;
|
|
while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_NAME )
|
|
{
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_DISPLAY_NAME was not found in the lpAdrList");
|
|
return FALSE;
|
|
}
|
|
}
|
|
LUIOut(L4,"Display Name: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
|
|
//Check to see if EntryID exists
|
|
idx=0;
|
|
while(lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ENTRYID )
|
|
{
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_ENTRYID was not found in the lpAdrList");
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// PROCEDURE: VerifyResolvedAdrList
|
|
// DESCRIPTION: Walk through a lpAdrList looking for PR_DISPLAY_NAME, PR_EMAIL_ADDRESS,
|
|
// PR_ADDRTYPE, PR_ENTRYID, and PR_OBJECT_TYPE. Each EID is sanity checked
|
|
// (lpb != NULL and cb != 0) and valid EIDs are passed to OpenEntry with
|
|
// a MailUser interface specified. If OpenEntry succedes, we assume the EID
|
|
// is a valid MailUser ID.
|
|
//
|
|
// PARAMETERS: LPADRLIST lpAdrList
|
|
// char* lpszInput - can be NULL to bypass match checking
|
|
//
|
|
|
|
BOOL VerifyResolvedAdrList(LPADRLIST lpAdrList, char* lpszInput)
|
|
{
|
|
extern LPADRBOOK glbllpAdrBook;
|
|
int i = 0, idx = 0, cMaxProps = 0;
|
|
BOOL Found = FALSE, retval = TRUE, localretval = TRUE;
|
|
ULONG cEntries = lpAdrList->cEntries;
|
|
ULONG cbLookupEID, ulObjType;
|
|
LPENTRYID lpLookupEID;
|
|
HRESULT hr;
|
|
LPUNKNOWN lpUnk=NULL;
|
|
LPADRBOOK lpAdrBook;
|
|
LPCIID lpcIID;
|
|
LPVOID Reserved1=NULL;
|
|
DWORD Reserved2=0;
|
|
// LPWABOBJECT lpWABObject2;
|
|
|
|
|
|
/* kludge to work around multiple wabopen/release bug, storing adrbook ptr
|
|
in a global variable
|
|
|
|
hr = WABOpen(&lpAdrBook, &lpWABObject2, Reserved1, Reserved2);
|
|
if (hr != S_OK) {
|
|
LUIOut(L4, "WABOpen FAILED. Couldn't obtain IAdrBook.");
|
|
retval = FALSE;
|
|
}
|
|
|
|
*/
|
|
#ifdef WAB
|
|
lpAdrBook = glbllpAdrBook;
|
|
lpAdrBook->AddRef();
|
|
#endif //WAB
|
|
|
|
|
|
// Walk through each AdrList entry
|
|
for(i=0; ((i<(int) lpAdrList->cEntries) && (!Found)); ++i) {
|
|
LUIOut(L3, "Searching Entry #%i out of %i", i+1, cEntries);
|
|
cMaxProps = (int)lpAdrList->aEntries[i].cValues;
|
|
|
|
//Check to see if Display Name exists
|
|
idx=0; localretval = TRUE;
|
|
while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_NAME )
|
|
&& localretval) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_DISPLAY_NAME was not found in lpAdrList entry #%i",i);
|
|
localretval = FALSE; retval = FALSE;
|
|
goto skip;
|
|
}
|
|
}
|
|
LUIOut(L4,"Display Name: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
if (lpszInput) {
|
|
if (!lstrcmp(lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ,lpszInput)) {
|
|
LUIOut(L3, "Found the entry we just added");
|
|
Found = TRUE;
|
|
}
|
|
else {
|
|
LUIOut(L3, "Did not find the entry we just added");
|
|
retval = FALSE;
|
|
}
|
|
}
|
|
|
|
//Check to see if EntryID exists
|
|
LUIOut(L3, "Verifying a PR_ENTRYID entry exists in the PropertyTagArray");
|
|
idx=0; localretval = TRUE;
|
|
while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ENTRYID )
|
|
&& localretval) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_ENTRYID was not found in the lpAdrList");
|
|
localretval = FALSE; retval = FALSE;
|
|
goto skip;
|
|
}
|
|
}
|
|
if (idx < cMaxProps) {
|
|
// Store EID for call to OpenEntry
|
|
lpLookupEID = (ENTRYID*)lpAdrList->aEntries[i].rgPropVals[idx].Value.bin.lpb;
|
|
cbLookupEID = lpAdrList->aEntries[i].rgPropVals[idx].Value.bin.cb;
|
|
if ((cbLookupEID == 0) || (lpLookupEID == NULL)) {
|
|
LUIOut(L4, "EntryID found, but is NULL or has size = 0. Test FAILED");
|
|
retval = FALSE;
|
|
goto skip;
|
|
}
|
|
else LUIOut(L4, "EntryID found and appears to be valid (not NULL and >0 size).");
|
|
// Try calling OpenEntry on the returned EID specifying a mailuser interface
|
|
LUIOut(L4, "Calling OpenEntry on the EntryID");
|
|
lpcIID = &IID_IMailUser;
|
|
hr = lpAdrBook->OpenEntry(cbLookupEID, lpLookupEID, lpcIID,
|
|
MAPI_BEST_ACCESS, &ulObjType, &lpUnk);
|
|
switch(hr) {
|
|
case S_OK:
|
|
if ((lpUnk) && (ulObjType==MAPI_MAILUSER))
|
|
LUIOut(L4, "OpenEntry call succeded on this EntryID and returned a valid object pointer and type.");
|
|
else {
|
|
LUIOut(L4, "OpenEntry call succeded on this EntryID but returned an invalid object pointer or incorrect type. Test FAILED");
|
|
retval = FALSE;
|
|
}
|
|
break;
|
|
case MAPI_E_NOT_FOUND:
|
|
LUIOut(L4, "OpenEntry returned MAPI_E_NOT_FOUND for this EntryID. Test FAILED");
|
|
retval = FALSE;
|
|
break;
|
|
case MAPI_E_UNKNOWN_ENTRYID:
|
|
LUIOut(L4, "OpenEntry returned MAPI_E_UNKNOWN_ENTRYID for this EntryID. Test FAILED");
|
|
retval = FALSE;
|
|
break;
|
|
case MAPI_E_NO_ACCESS:
|
|
LUIOut(L4, "OpenEntry returned MAPI_E_NO_ACCESS for this EntryID. Test FAILED");
|
|
retval = FALSE;
|
|
break;
|
|
default:
|
|
LUIOut(L4, "OpenEntry returned unknown result code (0x%x) for this EntryID. Test FAILED", hr);
|
|
retval = FALSE;
|
|
lpUnk = NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//Check to see if PR_EMAIL_ADDRESS exists
|
|
LUIOut(L3, "Verifying a PR_EMAIL_ADDRESS entry exists in the PropertyTagArray");
|
|
idx=0; localretval = TRUE;
|
|
while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_EMAIL_ADDRESS )
|
|
&& localretval) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_EMAIL_ADDRESS was not found in the lpAdrList");
|
|
localretval = FALSE; //retval = FALSE;
|
|
}
|
|
}
|
|
if (idx < cMaxProps) {
|
|
LUIOut(L4,"Email Address: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
}
|
|
|
|
//Check to see if PR_ADDRTYPE exists
|
|
LUIOut(L3, "Verifying a PR_ADDRTYPE entry exists in the PropertyTagArray");
|
|
idx=0; localretval = TRUE;
|
|
while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ADDRTYPE )
|
|
&& localretval) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_ADDRTYPE was not found in the lpAdrList");
|
|
localretval = FALSE; //retval = FALSE;
|
|
}
|
|
}
|
|
if (idx < cMaxProps) {
|
|
LUIOut(L4,"Address Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
}
|
|
|
|
//Check to see if PR_OBJECT_TYPE exists
|
|
LUIOut(L3, "Verifying a PR_OBJECT_TYPE entry exists in the PropertyTagArray");
|
|
idx=0; localretval = TRUE;
|
|
while((lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_OBJECT_TYPE )
|
|
&& localretval) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_OBJECT_TYPE was not found in the lpAdrList");
|
|
localretval = FALSE; retval = FALSE;
|
|
}
|
|
}
|
|
if (idx < cMaxProps) {
|
|
switch (lpAdrList->aEntries[i].rgPropVals[idx].Value.l) {
|
|
case MAPI_MAILUSER:
|
|
LUIOut(L4, "Object Type: MAPI_MAILUSER");
|
|
break;
|
|
case MAPI_DISTLIST:
|
|
LUIOut(L4, "Object Type: MAPI_DISTLIST");
|
|
break;
|
|
default:
|
|
LUIOut(L4,"Object Type not MAILUSER or DISTLIST. Test FAILED");
|
|
}
|
|
}
|
|
|
|
|
|
skip: // skip the current entry and continue through the lpAdrList
|
|
if (lpUnk) lpUnk->Release(); //Release the object returned from OpenEntry
|
|
}
|
|
if (lpAdrBook) lpAdrBook->Release();
|
|
//if (lpWABObject2) lpWABObject->Release();
|
|
return(retval);
|
|
}
|
|
|
|
BOOL DisplayAdrList(LPADRLIST lpAdrList, ULONG cEntries)
|
|
{
|
|
int i = 0;
|
|
int idx = 0;
|
|
int cMaxProps = 0;
|
|
BOOL Found, retval = TRUE;
|
|
|
|
for(i=0; i<(int) cEntries; ++i) {
|
|
LUIOut(L3, "Searching Entry #%i out of %i", i+1, cEntries);
|
|
cMaxProps = (int)lpAdrList->aEntries[i].cValues;
|
|
/*
|
|
//Check to see if Email Address Type exists
|
|
idx=0; Found = TRUE;
|
|
while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ADDRTYPE ) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_ADDRTYPE was not found in the lpAdrList");
|
|
Found = FALSE;
|
|
}
|
|
}
|
|
if (Found) LUIOut(L4,"Address Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
|
|
//Check to see if Email Address exists
|
|
idx=0; Found = TRUE;
|
|
while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_OBJECT_TYPE ) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_OBJECT_TYPE was not found in the lpAdrList");
|
|
Found = FALSE;
|
|
}
|
|
}
|
|
if (Found) LUIOut(L4,"Object Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
|
|
//Check to see if display type exists
|
|
idx=0; Found = TRUE;
|
|
while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_TYPE ) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_DISPLAY_TYPE was not found in the lpAdrList");
|
|
Found = FALSE;
|
|
}
|
|
}
|
|
if (Found) LUIOut(L4,"Display Type: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
|
|
*/
|
|
//Check to see if Display Name exists
|
|
idx=0; Found = TRUE;
|
|
while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_DISPLAY_NAME ) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_DISPLAY_NAME was not found in the lpAdrList");
|
|
Found = FALSE;
|
|
}
|
|
}
|
|
if (Found) LUIOut(L4,"Display Name: %s",lpAdrList->aEntries[i].rgPropVals[idx].Value.LPSZ);
|
|
|
|
//Check to see if EntryID exists
|
|
idx=0; Found = TRUE;
|
|
while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_ENTRYID ) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_ENTRYID was not found in the lpAdrList");
|
|
Found = FALSE;
|
|
}
|
|
}
|
|
if (Found) LUIOut(L4,"Entry ID Found");
|
|
//Check to see if Recipient Type exists
|
|
idx=0; Found = TRUE;
|
|
while(Found && lpAdrList->aEntries[i].rgPropVals[idx].ulPropTag != PR_RECIPIENT_TYPE ) {
|
|
idx++;
|
|
if(idx == cMaxProps) {
|
|
LUIOut(L4, "PR_RECIPIENT_TYPE was not found in the lpAdrList");
|
|
Found = FALSE;
|
|
}
|
|
}
|
|
if (Found) {
|
|
switch((ULONG)lpAdrList->aEntries[i].rgPropVals[idx].Value.l) {
|
|
case MAPI_TO: {
|
|
LUIOut(L4, "Recipient Type: [TO:]");
|
|
break;
|
|
}
|
|
case MAPI_CC: {
|
|
LUIOut(L4, "Recipient Type: [CC:]");
|
|
break;
|
|
}
|
|
case MAPI_BCC: {
|
|
LUIOut(L4, "Recipient Type: [BCC:]");
|
|
break;
|
|
}
|
|
default: {
|
|
LUIOut(L4, "Recipient Type: [UNKNOWN]. Test FAILED");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
|
|
BOOL LogIt(HRESULT hr, int Level,char * LogString)
|
|
{
|
|
switch (Level) {
|
|
|
|
case 0:
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(LFAIL, "%s",LogString);
|
|
return FALSE;
|
|
}
|
|
else LUIOut(LPASS,"%s",LogString);
|
|
return TRUE;
|
|
|
|
case 1:
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(LFAIL1, "%s",LogString);
|
|
return FALSE;
|
|
}
|
|
else LUIOut(LPASS1,"%s",LogString);
|
|
return TRUE;
|
|
case 2:
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(LFAIL2, "%s",LogString);
|
|
return FALSE;
|
|
}
|
|
else LUIOut(LPASS2,"%s",LogString);
|
|
return TRUE;
|
|
|
|
case 3:
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(LFAIL3, "%s",LogString);
|
|
return FALSE;
|
|
}
|
|
else LUIOut(LPASS3,"%s",LogString);
|
|
return TRUE;
|
|
|
|
case 4:
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(LFAIL4, "%s",LogString);
|
|
return FALSE;
|
|
}
|
|
else LUIOut(LPASS4,"%s",LogString);
|
|
return TRUE;
|
|
|
|
default: break;
|
|
}
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(LFAIL2, "%s",LogString);
|
|
return FALSE;
|
|
}
|
|
else LUIOut(LPASS2,"%s",LogString);
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// PROCEDURE: AllocateAdrList
|
|
// DESCRIPTION: Uses either MAPI or WAB allocaters to allocate an lpAdrList
|
|
//
|
|
// PARAMETERS: LPWABOBJECT lpLocalWABObject - ptr to opened WABObject
|
|
// int nEntries - how many AdrEntries to allocate
|
|
// int nProps - how many properties per AdrEntry
|
|
// LPADRLIST * lppAdrList - where to return the allocated ptr
|
|
//
|
|
|
|
BOOL AllocateAdrList(IN LPWABOBJECT lpLocalWABObject, IN int nEntries, IN int nProps, OUT LPADRLIST * lppAdrList) {
|
|
BOOL retval = TRUE;
|
|
SCODE sc;
|
|
|
|
*lppAdrList = NULL;
|
|
#ifdef PAB
|
|
if (! (sc = MAPIAllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)),
|
|
(void **)lppAdrList))) {
|
|
(*lppAdrList)->cEntries = nEntries;
|
|
for (int entry = 0; entry < nEntries; entry++) {
|
|
(*lppAdrList)->aEntries[entry].ulReserved1 = 0;
|
|
(*lppAdrList)->aEntries[entry].cValues = nProps;
|
|
sc = MAPIAllocateBuffer((nProps * sizeof(SPropValue)),
|
|
(void **)(&(*lppAdrList)->aEntries[entry].rgPropVals));
|
|
if (sc != S_OK) retval = FALSE;
|
|
}
|
|
}
|
|
else retval = FALSE;
|
|
|
|
//
|
|
// Should do cleanup here for a partial allocation that fails
|
|
//
|
|
|
|
#endif //PAB
|
|
#ifdef WAB
|
|
if (! (sc = lpLocalWABObject->AllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)),
|
|
(void **)lppAdrList))) {
|
|
(*lppAdrList)->cEntries = nEntries;
|
|
for (int entry = 0; entry < nEntries; entry++) {
|
|
(*lppAdrList)->aEntries[entry].ulReserved1 = 0;
|
|
(*lppAdrList)->aEntries[entry].cValues = nProps;
|
|
sc = lpLocalWABObject->AllocateBuffer((nProps * sizeof(SPropValue)),
|
|
(void **)(&(*lppAdrList)->aEntries[entry].rgPropVals));
|
|
if (sc != S_OK) retval = FALSE;
|
|
}
|
|
}
|
|
else retval = FALSE;
|
|
|
|
//
|
|
// Should do cleanup here for a partial allocation that fails
|
|
//
|
|
#endif //WAB
|
|
return retval;
|
|
}
|
|
|
|
//
|
|
// PROCEDURE: GrowAdrList
|
|
// DESCRIPTION: Takes an existing lpAdrList, allocates a new, larger lpAdrList
|
|
// , copies over the old entries and allocates new entries, returning
|
|
// a pointer to the new AdrList in lpAdrList.
|
|
//
|
|
// PARAMETERS: int nEntries - how many AdrEntries to allocate in new list
|
|
// int nProps - how many properties per new AdrEntry
|
|
// LPADRLIST * lppAdrList - where to return the allocated ptr
|
|
//
|
|
|
|
BOOL GrowAdrList(IN UINT nEntries, IN UINT nProps, OUT LPADRLIST * lppAdrList) {
|
|
BOOL retval = TRUE;
|
|
SCODE sc;
|
|
LPADRLIST lpTempAdrList;
|
|
unsigned int entry;
|
|
|
|
|
|
if ((!lppAdrList) || ((*lppAdrList)->cEntries>=nEntries))
|
|
return FALSE;
|
|
|
|
#ifdef PAB
|
|
if (! (sc = MAPIAllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)),
|
|
(void **)&lpTempAdrList))) {
|
|
lpTempAdrList->cEntries = nEntries;
|
|
// Copy over old entries
|
|
entry = (*lppAdrList)->cEntries;
|
|
memcpy(lpTempAdrList, *lppAdrList, (entry * sizeof(ADRENTRY)));
|
|
// Allocate new entries
|
|
for (; entry < nEntries; entry++) {
|
|
lpTempAdrList->aEntries[entry].ulReserved1 = 0;
|
|
lpTempAdrList->aEntries[entry].cValues = nProps;
|
|
sc = MAPIAllocateBuffer((nProps * sizeof(SPropValue)),
|
|
(void **)(&lpTempAdrList->aEntries[entry].rgPropVals));
|
|
if (sc != S_OK) retval = FALSE;
|
|
}
|
|
FreeAdrList(lppAdrList);
|
|
*lppAdrList = lpTempAdrList;
|
|
}
|
|
else retval = FALSE;
|
|
|
|
//
|
|
// Should do cleanup here for a partial allocation that fails
|
|
//
|
|
|
|
#endif //PAB
|
|
#ifdef WAB
|
|
if (! (sc = lpWABObject->AllocateBuffer(sizeof(ADRLIST) + (nEntries * sizeof(ADRENTRY)),
|
|
(void **)&lpTempAdrList))) {
|
|
// Copy over old entries
|
|
entry = (*lppAdrList)->cEntries;
|
|
memcpy(lpTempAdrList, *lppAdrList, (sizeof(ADRLIST)+(entry * sizeof(ADRENTRY))));
|
|
lpTempAdrList->cEntries = nEntries;
|
|
// Allocate new entries
|
|
for (; entry < nEntries; entry++) {
|
|
lpTempAdrList->aEntries[entry].ulReserved1 = 0;
|
|
lpTempAdrList->aEntries[entry].cValues = nProps;
|
|
sc = lpWABObject->AllocateBuffer((nProps * sizeof(SPropValue)),
|
|
(void **)(&lpTempAdrList->aEntries[entry].rgPropVals));
|
|
if (sc != S_OK) retval = FALSE;
|
|
}
|
|
FreePartAdrList(lppAdrList);
|
|
*lppAdrList = lpTempAdrList;
|
|
}
|
|
else retval = FALSE;
|
|
|
|
//
|
|
// Should do cleanup here for a partial allocation that fails
|
|
//
|
|
|
|
#endif //WAB
|
|
return retval;
|
|
}
|
|
|
|
|
|
//
|
|
// PROCEDURE: FreeAdrList
|
|
// DESCRIPTION: Uses either MAPI or WAB de-allocaters to walk and free an lpAdrList
|
|
//
|
|
// PARAMETERS: LPWABOBJECT lpLocalWABObject - ptr to opened WABObject
|
|
// LPADRLIST * lppAdrList - where the lpAdrList to free is stored
|
|
//
|
|
|
|
BOOL FreeAdrList(IN LPWABOBJECT lpLocalWABObject, IN LPADRLIST * lppAdrList) {
|
|
LPADRLIST lpAdrList = NULL;
|
|
UINT idx;
|
|
|
|
if (lppAdrList) lpAdrList = *lppAdrList;
|
|
|
|
#ifdef PAB
|
|
if (lpAdrList) {
|
|
for (idx = 0; idx < lpAdrList->cEntries; idx++)
|
|
MAPIFreeBuffer(lpAdrList->aEntries[idx].rgPropVals);
|
|
MAPIFreeBuffer(lpAdrList);
|
|
*lppAdrList=NULL;
|
|
}
|
|
#endif //PAB
|
|
#ifdef WAB
|
|
if (lpAdrList) {
|
|
for (idx = 0; idx < lpAdrList->cEntries; idx++)
|
|
lpLocalWABObject->FreeBuffer(lpAdrList->aEntries[idx].rgPropVals);
|
|
lpLocalWABObject->FreeBuffer(lpAdrList);
|
|
*lppAdrList=NULL;
|
|
}
|
|
#endif //WAB
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// PROCEDURE: FreePartAdrList
|
|
// DESCRIPTION: Uses either MAPI or WAB de-allocaters to free an lpAdrList
|
|
// but not the associated properties.
|
|
//
|
|
// PARAMETERS: LPADRLIST * lppAdrList - where the lpAdrList to free is stored
|
|
//
|
|
|
|
BOOL FreePartAdrList(IN LPADRLIST * lppAdrList) {
|
|
LPADRLIST lpAdrList = NULL;
|
|
|
|
if (lppAdrList) lpAdrList = *lppAdrList;
|
|
|
|
#ifdef PAB
|
|
if (lpAdrList) {
|
|
MAPIFreeBuffer(lpAdrList);
|
|
lpAdrList=NULL;
|
|
}
|
|
#endif //PAB
|
|
#ifdef WAB
|
|
if (lpAdrList) {
|
|
lpWABObject->FreeBuffer(lpAdrList);
|
|
lpAdrList=NULL;
|
|
}
|
|
#endif //WAB
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// PROCEDURE: FindProp
|
|
// DESCRIPTION: Walks through the properties of an AdrEntry and returns the index
|
|
// of the requested property tag.
|
|
//
|
|
// PARAMETERS: LPADRENTRY lpAdrEntry - Entry to search through
|
|
// ULONG ulPropTag - Property tag to look for
|
|
// unsigned int* lpnFoundIndex - Ptr to output variable where the found index
|
|
// value is to be stored.
|
|
//
|
|
// RETURNS: TRUE if succesfull.
|
|
//
|
|
|
|
BOOL FindProp(IN LPADRENTRY lpAdrEntry, IN ULONG ulPropTag, OUT unsigned int* lpnFoundIndex) {
|
|
|
|
if ((!lpAdrEntry) || (!ulPropTag) || (!lpnFoundIndex)) return(FALSE);
|
|
|
|
for (unsigned int Counter1 = 0; Counter1 < lpAdrEntry->cValues; Counter1++) {
|
|
if (lpAdrEntry->rgPropVals[Counter1].ulPropTag == ulPropTag) {
|
|
*lpnFoundIndex = Counter1;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// PROCEDURE: FindPropinRow
|
|
// DESCRIPTION: Walks through the properties of an SRowSet and returns the index
|
|
// of the requested property tag.
|
|
//
|
|
// PARAMETERS: LPSRow lpRow - Row to search through
|
|
// ULONG ulPropTag - Property tag to look for
|
|
// unsigned int* lpnFoundIndex - Ptr to output variable where the found index
|
|
// value is to be stored.
|
|
//
|
|
// RETURNS: TRUE if succesfull.
|
|
//
|
|
|
|
BOOL FindPropinRow(IN LPSRow lpRow, IN ULONG ulPropTag, OUT unsigned int* lpnFoundIndex) {
|
|
|
|
if ((!lpRow) || (!ulPropTag) || (!lpnFoundIndex)) return(FALSE);
|
|
|
|
|
|
for (ULONG Column = 0; Column < lpRow->cValues; Column++) {
|
|
if (lpRow->lpProps[Column].ulPropTag == ulPropTag) {
|
|
*lpnFoundIndex = Column;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// PROCEDURE: ParseIniBuffer
|
|
// DESCRIPTION: Walks through a buffer read from an ini file which contains
|
|
// several strings separated by quotation marks and copies the
|
|
// requested string to the users buffer.
|
|
//
|
|
// PARAMETERS: LPSTR lpszIniBuffer
|
|
// UINT uSelect - which string (in order left to right starting with 1 ) to return
|
|
// LPSTR lpszReturnBuffer - pre-alocated by caller and dumb (assumes enough space)
|
|
//
|
|
|
|
BOOL ParseIniBuffer(LPSTR lpszIniBuffer, UINT uSelect, LPSTR lpszReturnBuffer) {
|
|
UINT Selected = 0;
|
|
|
|
// while (*(lpszIniBuffer++) != '"'); // Advance to first entry
|
|
// lpszIniBuffer++;
|
|
Selected++; // Now pointing at 1st letter of first item
|
|
while(uSelect != Selected++) {
|
|
while (*(lpszIniBuffer++) != '"'); // Advance to end of this entry
|
|
while (*(lpszIniBuffer++) != '"'); // Advance to beginning of next entry
|
|
// Now we are pointing at the 1st letter of the desired entry so copy
|
|
}
|
|
while((*(lpszIniBuffer) != '"') && (*(lpszIniBuffer) != '\0')) {
|
|
*(lpszReturnBuffer++) = *lpszIniBuffer++;
|
|
}
|
|
*lpszReturnBuffer = '\0'; // Add the terminator
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
//
|
|
// PROCEDURE: PropError
|
|
// DESCRIPTION: Compares the passed in property type with PT_ERROR returning TRUE is error is found
|
|
//
|
|
// PARAMETERS: ulPropTag - Tag to compare
|
|
// cValues - # of entries returned from GetProps
|
|
//
|
|
|
|
BOOL PropError(ULONG ulPropTag, ULONG cValues) {
|
|
BOOL retval = FALSE;
|
|
#ifdef DISTLISTS
|
|
for(ULONG Counter = 0; Counter < cValues; Counter++) {
|
|
if (PROP_TYPE(ulPropTag) == PT_ERROR) retval = TRUE;
|
|
}
|
|
#endif
|
|
return retval;
|
|
}
|
|
|
|
//
|
|
// PROCEDURE: DeleteWABFile
|
|
// DESCRIPTION: Reads the registry to determine the location of the WAB file,
|
|
// and deletes the file.
|
|
//
|
|
// PARAMETERS: none
|
|
//
|
|
|
|
BOOL DeleteWABFile () {
|
|
BOOL retval = TRUE;
|
|
long lretval;
|
|
HKEY hKey;
|
|
char KeyAddress[] = "Software\\Microsoft\\WAB\\Wab File Name";
|
|
DWORD dType, dSize = 256;
|
|
char achData[256];
|
|
|
|
if (!MyRegOpenKeyEx(HKEY_CURRENT_USER,
|
|
KeyAddress,
|
|
KEY_QUERY_VALUE,
|
|
&hKey)) {
|
|
LUIOut(L2, "MyRegOpenKeyEx call failed");
|
|
retval = FALSE;
|
|
return(retval);
|
|
}
|
|
|
|
|
|
lretval = RegQueryValueEx(hKey, // handle of key to query
|
|
NULL, // address of name of value to query
|
|
(LPDWORD)NULL, // reserved
|
|
&dType, // address of buffer for value type
|
|
(LPBYTE)achData, // address of data buffer
|
|
&dSize // address of data buffer size
|
|
);
|
|
|
|
if (lretval != ERROR_SUCCESS) {
|
|
LUIOut(L2, "RegQueryValueEx call failed with error code %u", lretval);
|
|
retval = FALSE;
|
|
return(retval);
|
|
}
|
|
|
|
LUIOut(L2, "Deleting WAB file: %s", achData);
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
if (!DeleteFile(achData)) {
|
|
LUIOut(L3, "Delete FAILED. Could not locate or delete file.");
|
|
retval = FALSE;
|
|
}
|
|
|
|
return(retval);
|
|
}
|
|
|
|
//
|
|
// PROCEDURE: MyRegOpenKeyEx
|
|
// DESCRIPTION: Walks through a null terminated string, such as "\Software\Microsoft\WAB"
|
|
// openning each key until it reaches the end and returns that open key (closing
|
|
// the interim keys along the way). The caller must close the returned HKEY.
|
|
//
|
|
// PARAMETERS: StartKey - one of the predefined "open" keys to root at
|
|
// szAddress - null terminated string specifcying the path to the key to be opened
|
|
// RegSec - the security access required (i.e. KEY_READ)
|
|
// lpReturnKey - address of HKEY where final opened key is stored
|
|
//
|
|
|
|
BOOL MyRegOpenKeyEx(HKEY StartKey, char* szAddress, REGSAM RegSec, HKEY* lpReturnKey) {
|
|
HKEY workkey1, workkey2, *lpOpenKey=&workkey1, *lpNewKey=&workkey2;
|
|
char workbuffer[256], *lpAddr = szAddress, *lpWork = workbuffer;
|
|
BOOL Started = FALSE, Done = FALSE;
|
|
long lretval;
|
|
|
|
if (!szAddress) return FALSE;
|
|
|
|
while (!Done) {
|
|
if (*lpAddr == '\\') lpAddr++; //skip over the initial backslash if it exists
|
|
while((*(lpAddr) != '\\') && (*(lpAddr) != '\0')) {
|
|
*(lpWork++) = *lpAddr++;
|
|
}
|
|
*lpWork = '\0'; // Add the terminator
|
|
if (*(lpAddr) == '\0') Done = TRUE;
|
|
lpWork = workbuffer;
|
|
if (!Started) {
|
|
//
|
|
// First, special case the starting key (predefined/open key root)
|
|
//
|
|
lretval = RegOpenKeyEx( StartKey,
|
|
lpWork,
|
|
DWORD(0),
|
|
RegSec,
|
|
lpOpenKey);
|
|
Started = TRUE;
|
|
}
|
|
else {
|
|
lretval = RegOpenKeyEx( *lpOpenKey,
|
|
lpWork,
|
|
DWORD(0),
|
|
RegSec,
|
|
lpNewKey);
|
|
RegCloseKey(*lpOpenKey);
|
|
*lpOpenKey = *lpNewKey;
|
|
}
|
|
if (lretval != ERROR_SUCCESS) {
|
|
LUIOut(L2, "RegOpenKeyEx call failed with error code 0x%x", lretval);
|
|
return(FALSE);
|
|
}
|
|
|
|
}
|
|
|
|
*lpReturnKey = *lpNewKey;
|
|
return(TRUE);
|
|
}
|
|
|
|
//
|
|
// PROCEDURE: CreateMultipleEntries
|
|
// DESCRIPTION: Creates multiple entries in the WAB using the display name stored in the
|
|
// pabtests.ini file CreateEntriesStress section.
|
|
//
|
|
// PARAMETERS: NumEntriesIn - how many entries to create. If 0, then the value is read
|
|
// from the same CreateEntriesStress section.
|
|
// lpPerfData - address of a dword data type to hold the average time in milliseconds
|
|
// required during SaveChanges. If NULL perf data is not accumulated.
|
|
//
|
|
|
|
BOOL CreateMultipleEntries(IN UINT NumEntriesIn, DWORD* lpPerfData)
|
|
{
|
|
|
|
ULONG ulFlags = 0;
|
|
HRESULT hr = hrSuccess;
|
|
SCODE sc = SUCCESS_SUCCESS;
|
|
int retval=TRUE;
|
|
DWORD StartTime, StopTime;
|
|
LPADRBOOK lpAdrBook = NULL;
|
|
LPABCONT lpABCont= NULL;
|
|
ULONG cbEidPAB = 0;
|
|
LPENTRYID lpEidPAB = NULL;
|
|
|
|
char EntProp[10][BIG_BUF]; //MAX_PROP
|
|
ULONG cValues = 0, ulObjType=NULL;
|
|
int i=0,k=0;
|
|
char EntryBuf[MAX_BUF];
|
|
char szDLTag[SML_BUF];
|
|
unsigned int NumEntries, counter, StrLen;
|
|
|
|
LPMAILUSER lpMailUser=NULL,lpDistList=NULL;
|
|
SPropValue PropValue[3] = {0}; // This value is 3 because we
|
|
// will be setting 3 properties:
|
|
// EmailAddress, DisplayName and
|
|
// AddressType.
|
|
|
|
LPSPropValue lpSPropValueAddress = NULL;
|
|
LPSPropValue lpSPropValueDL = NULL;
|
|
|
|
SizedSPropTagArray(1,SPTArrayAddress) = {1, {PR_DEF_CREATE_MAILUSER} };
|
|
SizedSPropTagArray(1,SPTArrayDL) = {1, {PR_DEF_CREATE_DL} };
|
|
|
|
if (!GetAB(OUT &lpAdrBook)) {
|
|
retval = FALSE;
|
|
goto out;
|
|
}
|
|
|
|
// Call IAddrBook::OpenEntry to get the root container to PAB - MAPI
|
|
|
|
assert(lpAdrBook != NULL);
|
|
hr = OpenPABID( IN lpAdrBook, OUT &cbEidPAB,
|
|
OUT &lpEidPAB,OUT &lpABCont, OUT &ulObjType);
|
|
|
|
|
|
// hr = lpAdrBook->OpenEntry(0, NULL, NULL,MAPI_MODIFY,&ulObjType, (LPUNKNOWN *) &lpABCont);
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(L2,"IAddrBook->OpenEntry Failed");
|
|
retval=FALSE;
|
|
goto out;
|
|
}
|
|
|
|
// Wipe perfdata if we're tracking this
|
|
if (lpPerfData) *lpPerfData = (DWORD)0;
|
|
//
|
|
// Try to create a MailUser entry in the container
|
|
//
|
|
|
|
|
|
// Need to get the template ID so we call GetProps with PR_DEF_CREATE_MAILUSER
|
|
assert(lpABCont != NULL);
|
|
hr = lpABCont->GetProps( IN (LPSPropTagArray) &SPTArrayAddress,
|
|
IN 0, //Flags
|
|
OUT &cValues,
|
|
OUT &lpSPropValueAddress);
|
|
|
|
if ((HR_FAILED(hr))||(PropError(lpSPropValueAddress->ulPropTag, cValues))) {
|
|
LUIOut(L3,"GetProps FAILED for Default MailUser template");
|
|
retval=FALSE;
|
|
goto out;
|
|
}
|
|
|
|
// The returned value of PR_DEF_CREATE_MAILUSER is an
|
|
// EntryID which can be passed to CreateEntry
|
|
//
|
|
|
|
// Retrieve user info from ini file
|
|
cValues = 3; //# of props we are setting
|
|
lstrcpy(szDLTag,"Address1");
|
|
GetPrivateProfileString("CreateEntriesStress",szDLTag,"",EntryBuf,MAX_BUF,INIFILENAME);
|
|
GetPropsFromIniBufEntry(EntryBuf,cValues,EntProp);
|
|
StrLen = (strlen(EntProp[0]));
|
|
_itoa(0,(char*)&EntProp[0][StrLen],10);
|
|
EntProp[0][StrLen+1]= '\0';
|
|
NumEntries = (NumEntriesIn > 0) ?
|
|
NumEntriesIn:GetPrivateProfileInt("CreateEntriesStress","NumCopies",0,INIFILENAME);
|
|
|
|
if (NumEntries > 100)
|
|
LUIOut(L2, "Adding %u MailUser entries to the WAB. This may take several minutes.", NumEntries);
|
|
for (counter = 0; counter < NumEntries; counter++) {
|
|
// LUIOut(L3, "Calling IABContainer->CreateEntry with the EID from GetProps");
|
|
hr = lpABCont->CreateEntry( IN lpSPropValueAddress->Value.bin.cb,
|
|
IN (LPENTRYID) lpSPropValueAddress->Value.bin.lpb,
|
|
IN 0,
|
|
OUT (LPMAPIPROP *) &lpMailUser);
|
|
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(L3,"CreateEntry failed for PR_DEF_CREATE_MAILUSER");
|
|
retval=FALSE;
|
|
goto out;
|
|
}
|
|
|
|
//
|
|
// Then set the properties
|
|
//
|
|
|
|
PropValue[0].ulPropTag = PR_DISPLAY_NAME;
|
|
PropValue[1].ulPropTag = PR_ADDRTYPE;
|
|
PropValue[2].ulPropTag = PR_EMAIL_ADDRESS;
|
|
|
|
|
|
|
|
_itoa(counter,(char*)&EntProp[0][StrLen],10);
|
|
// LUIOut(L2,"MailUser Entry to Add: %s",EntProp[0]);
|
|
|
|
for (i=0; i<(int)cValues;i++)
|
|
PropValue[i].Value.LPSZ = (LPTSTR)EntProp[i];
|
|
hr = lpMailUser->SetProps(IN cValues,
|
|
IN PropValue,
|
|
IN NULL);
|
|
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(L3,"MailUser->SetProps call FAILED for %s properties",PropValue[0].Value.LPSZ);
|
|
retval=FALSE;
|
|
goto out;
|
|
}
|
|
// else LUIOut(L3,"MailUser->SetProps call PASSED for %s properties",PropValue[0].Value.LPSZ);
|
|
|
|
StartTime = GetTickCount();
|
|
hr = lpMailUser->SaveChanges(IN KEEP_OPEN_READWRITE); //flags
|
|
StopTime = GetTickCount();
|
|
/* if (lpPerfData) {
|
|
if ((StopTime-StartTime) > *lpPerfData)
|
|
*lpPerfData = (StopTime - StartTime);
|
|
}
|
|
*/
|
|
if (lpPerfData) {
|
|
*lpPerfData += (StopTime - StartTime);
|
|
}
|
|
|
|
if (HR_FAILED(hr)) {
|
|
LUIOut(L3,"MailUser->SaveChanges FAILED");
|
|
retval=FALSE;
|
|
goto out;
|
|
}
|
|
// else LUIOut(L3,"MailUser->SaveChanges PASSED, entry added to PAB/WAB");
|
|
|
|
if (lpMailUser) {
|
|
lpMailUser->Release();
|
|
lpMailUser = NULL;
|
|
}
|
|
|
|
}
|
|
if (lpPerfData)
|
|
*lpPerfData /= NumEntries;
|
|
|
|
|
|
out:
|
|
#ifdef PAB
|
|
if (lpEid)
|
|
MAPIFreeBuffer(lpEid);
|
|
if (lpEidPAB)
|
|
MAPIFreeBuffer(lpEidPAB);
|
|
if (lpSPropValueAddress)
|
|
MAPIFreeBuffer(lpSPropValueAddress);
|
|
|
|
if (lpSPropValueDL)
|
|
MAPIFreeBuffer(lpSPropValueDL);
|
|
|
|
#endif
|
|
#ifdef WAB
|
|
if (lpEidPAB)
|
|
lpWABObject->FreeBuffer(lpEidPAB);
|
|
if (lpSPropValueAddress)
|
|
lpWABObject->FreeBuffer(lpSPropValueAddress);
|
|
|
|
if (lpSPropValueDL)
|
|
lpWABObject->FreeBuffer(lpSPropValueDL);
|
|
|
|
#endif
|
|
if (lpMailUser)
|
|
lpMailUser->Release();
|
|
|
|
if (lpDistList)
|
|
lpDistList->Release();
|
|
|
|
if (lpABCont)
|
|
lpABCont->Release();
|
|
|
|
if (lpAdrBook)
|
|
lpAdrBook->Release();
|
|
|
|
#ifdef PAB
|
|
if (lpMAPISession)
|
|
lpMAPISession->Release();
|
|
|
|
MAPIUninitialize();
|
|
#endif
|
|
#ifdef WAB
|
|
if (lpWABObject) {
|
|
lpWABObject->Release();
|
|
lpWABObject = NULL;
|
|
}
|
|
#endif
|
|
|
|
return retval;
|
|
}
|
|
|
|
void GenerateRandomPhoneNumber(char **lppPhone) {
|
|
#define FORMATSIZE 15 // Size of formatted phone# + terminator i.e. (206)-882-8080
|
|
#define MAXNUMSIZE (FORMATSIZE + 32)
|
|
unsigned int Offset = 0;
|
|
extern BOOL Seeded;
|
|
*lppPhone = (char*)LocalAlloc(LMEM_FIXED, MAXNUMSIZE*sizeof(char));
|
|
(*lppPhone)[0] = '\0'; // Set the first char to a terminator
|
|
|
|
// seed the random number generator with the current time
|
|
if (!Seeded) {
|
|
srand( (unsigned)GetTickCount());
|
|
Seeded = TRUE;
|
|
}
|
|
while (Offset < FORMATSIZE) {
|
|
_itoa(rand(), ((*lppPhone)+Offset), 10);
|
|
Offset = strlen(*lppPhone);
|
|
}
|
|
// Overwrite some numbers with formatting characters
|
|
(*lppPhone)[0] = '(';
|
|
(*lppPhone)[4] = ')';
|
|
(*lppPhone)[5] = '-';
|
|
(*lppPhone)[9] = '-';
|
|
(*lppPhone)[FORMATSIZE-1] = '\0'; //Cutoff the end in case it's > FORMATSIZE
|
|
}
|
|
|
|
void GenerateRandomText(char **lppText, UINT unSize) {
|
|
unsigned int Offset = 0;
|
|
extern BOOL Seeded;
|
|
extern ULONG glblTest, glblCount, glblDN;
|
|
*lppText = (char*)LocalAlloc(LMEM_FIXED, (unSize+1)*sizeof(char));
|
|
|
|
// seed the random number generator with the current time
|
|
if (!Seeded) {
|
|
srand( (unsigned)GetTickCount());
|
|
Seeded = TRUE;
|
|
}
|
|
#ifdef TESTPASS
|
|
for (Offset = 0; Offset < unSize; Offset++) {
|
|
(*lppText)[Offset] = (char)glblTest;
|
|
if ((*lppText)[Offset] == '\0') (*lppText)[Offset] = (char)'?'; //don't want a terminator mid string
|
|
}
|
|
(*lppText)[unSize] = '\0'; //Cutoff the end
|
|
if (glblDN) {
|
|
glblDN = 0;
|
|
if (++glblCount == 15) {
|
|
glblTest++;
|
|
glblCount=0;
|
|
LUIOut(L4, "Testing value %i [%c].", glblTest, glblTest);
|
|
}
|
|
}
|
|
#else
|
|
for (Offset = 0; Offset < unSize; Offset++) {
|
|
(*lppText)[Offset] = rand();
|
|
if ((*lppText)[Offset] == '\0') (*lppText)[Offset] = (char)'?'; //don't want a terminator mid string
|
|
}
|
|
(*lppText)[unSize] = '\0'; //Cutoff the end
|
|
#endif
|
|
}
|
|
|
|
void GenerateRandomBoolean(unsigned short *lpBool) {
|
|
extern BOOL Seeded;
|
|
|
|
// seed the random number generator with the current time
|
|
if (!Seeded) {
|
|
srand( (unsigned)GetTickCount());
|
|
Seeded = TRUE;
|
|
}
|
|
|
|
*lpBool = (unsigned short)(GetTickCount() & 0x01); //If bit 0 is set then true otherwise false
|
|
}
|
|
|
|
void GenerateRandomLong(long *lpLong) {
|
|
extern BOOL Seeded;
|
|
|
|
// seed the random number generator with the current time
|
|
if (!Seeded) {
|
|
srand( (unsigned)GetTickCount());
|
|
Seeded = TRUE;
|
|
}
|
|
*lpLong = (long)rand();
|
|
}
|
|
|
|
void GenerateRandomBinary(SBinary *lpBinary, UINT unSize) {
|
|
unsigned int Offset = 0;
|
|
extern BOOL Seeded;
|
|
lpBinary->lpb = (LPBYTE)LocalAlloc(LMEM_FIXED, unSize);
|
|
lpBinary->cb = unSize;
|
|
// seed the random number generator with the current time
|
|
if (!Seeded) {
|
|
srand( (unsigned)GetTickCount());
|
|
Seeded = TRUE;
|
|
}
|
|
|
|
for (Offset = 0; Offset < unSize; Offset++) {
|
|
lpBinary->lpb[Offset] = (BYTE)(rand() * 255)/RAND_MAX;
|
|
}
|
|
}
|
|
|
|
//***
|
|
//*** set unCount to AUTONUM_OFF to disable autonumbering display names
|
|
//*** if lppDisplayName is not NULL then the *lppDisplayName string is used for the prefix of
|
|
//*** the DN and the ptr to the completed DisplayName is returned to the callee if lppReturnName is not NULL
|
|
//***
|
|
void CreateProps(LPTSTR lpszFileName, LPTSTR lpszSection, SPropValue** lppProperties, ULONG* lpcValues, UINT unCount, char** lppDisplayName, char ** lppReturnName) {
|
|
UINT StrLen1, PropIndex = 0, Properties = 0; //How many props does the user want to set
|
|
char *lpszLocalDisplayName, DNText[] = {"Test Entry #"};
|
|
extern ULONG glblDN;
|
|
PropTableEntry* lpEntry = PropTable;
|
|
|
|
while (lpEntry->ulPropTag) {
|
|
lpEntry->unSize = GetPrivateProfileInt(lpszSection,lpEntry->lpszPropTag,0,lpszFileName);
|
|
if ((lpEntry->ulPropTag == PR_DISPLAY_NAME) && (unCount != AUTONUM_OFF))
|
|
lpEntry->unSize = TRUE; //If we're autonumbering the display name, then make sure unsize is not zero
|
|
if (lpEntry->unSize) Properties++;
|
|
lpEntry++;
|
|
}
|
|
|
|
//At this point, any table entry with nonzero size we need to create
|
|
//LUIOut(L3, "Setting %i properties.", Properties);
|
|
*lpcValues = Properties;
|
|
*lppProperties = (SPropValue*)LocalAlloc(LMEM_FIXED, (Properties * sizeof(SPropValue)));
|
|
lpEntry = PropTable;
|
|
|
|
while (lpEntry->ulPropTag) {
|
|
if (lpEntry->unSize) {
|
|
//special case phone numbers
|
|
if ((strstr(lpEntry->lpszPropTag, "PHONE")) || (strstr(lpEntry->lpszPropTag, "FAX"))) {
|
|
//LUIOut(L3, "Found a prop I think is a phone number, called %s.", lpEntry->lpszPropTag);
|
|
(*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag;
|
|
GenerateRandomPhoneNumber(&((*lppProperties)[PropIndex].Value.LPSZ));
|
|
}
|
|
//special case for autonumbering display names if requested
|
|
else if ((lpEntry->ulPropTag == PR_DISPLAY_NAME) && (unCount != AUTONUM_OFF)) {
|
|
if ((lppDisplayName)&&(*lppDisplayName)) {
|
|
//Caller passed in a string to use as the prefix
|
|
StrLen1 = strlen(*lppDisplayName);
|
|
lpszLocalDisplayName = (char*)LocalAlloc(LMEM_FIXED, (StrLen1+5)*sizeof(char)); //5 for terminator plus # up to 9999
|
|
strcpy(lpszLocalDisplayName, *lppDisplayName);
|
|
}
|
|
else {
|
|
StrLen1 = strlen(DNText);
|
|
lpszLocalDisplayName = (char*)LocalAlloc(LMEM_FIXED, (StrLen1+5)*sizeof(char)); //5 for terminator plus # up to 9999
|
|
strcpy(lpszLocalDisplayName, DNText);
|
|
}
|
|
// Add the Entry # to the display name
|
|
_itoa(unCount,(char*)&(lpszLocalDisplayName[StrLen1]),10);
|
|
(*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag;
|
|
(*lppProperties)[PropIndex].Value.LPSZ = lpszLocalDisplayName;
|
|
if (lppReturnName) *lppReturnName = lpszLocalDisplayName;
|
|
}
|
|
else {
|
|
switch(PROP_TYPE(lpEntry->ulPropTag)) {
|
|
case PT_STRING8:
|
|
(*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag;
|
|
#ifdef TESTPASS
|
|
if (lpEntry->ulPropTag == PR_DISPLAY_NAME) glblDN = 1;
|
|
#endif
|
|
GenerateRandomText(&((*lppProperties)[PropIndex].Value.LPSZ),lpEntry->unSize);
|
|
if ((lpEntry->ulPropTag == PR_DISPLAY_NAME) && lppReturnName)
|
|
*lppReturnName = (*lppProperties)[PropIndex].Value.LPSZ;
|
|
break;
|
|
case PT_BOOLEAN:
|
|
(*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag;
|
|
GenerateRandomBoolean(&((*lppProperties)[PropIndex].Value.b));
|
|
break;
|
|
case PT_LONG:
|
|
(*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag;
|
|
GenerateRandomLong(&((*lppProperties)[PropIndex].Value.l));
|
|
break;
|
|
case PT_BINARY:
|
|
(*lppProperties)[PropIndex].ulPropTag = lpEntry->ulPropTag;
|
|
GenerateRandomBinary(&((*lppProperties)[PropIndex].Value.bin),lpEntry->unSize);
|
|
break;
|
|
default:
|
|
LUIOut(L1, "Unrecognized prop type 0x%x for property %s", PROP_TYPE(lpEntry->ulPropTag), lpEntry->lpszPropTag);
|
|
}
|
|
}
|
|
PropIndex++;
|
|
}
|
|
lpEntry++;
|
|
}
|
|
|
|
}
|
|
|
|
//***
|
|
//*** Walks through the expected props and searches the found props for the same prop/value combo
|
|
//***
|
|
BOOL CompareProps(SPropValue* lpExpectedProps, ULONG cValuesExpected, SPropValue* lpCompareProps, ULONG cValuesCompare) {
|
|
ULONG TargetProp, CompareIndex;
|
|
BOOL Result = TRUE, Found;
|
|
for (ULONG PropertyIndex = 0; PropertyIndex < cValuesExpected; PropertyIndex++) {
|
|
TargetProp = lpExpectedProps[PropertyIndex].ulPropTag;
|
|
for (CompareIndex = 0, Found = FALSE; CompareIndex < cValuesCompare; CompareIndex++) {
|
|
if (lpCompareProps[CompareIndex].ulPropTag == TargetProp) {
|
|
//if (TargetProp == PR_DISPLAY_NAME) _asm{int 3};
|
|
Found = TRUE;
|
|
switch(PROP_TYPE(TargetProp)) {
|
|
case PT_STRING8:
|
|
if (strcmp(lpExpectedProps[PropertyIndex].Value.LPSZ, lpCompareProps[CompareIndex].Value.LPSZ)) {
|
|
//Strings did not match so fail compare
|
|
LUIOut(L3, "Comparison failed for prop 0x%x. Expected %s but found %s", TargetProp, lpExpectedProps[PropertyIndex].Value.LPSZ, lpCompareProps[CompareIndex].Value.LPSZ);
|
|
Result = FALSE;
|
|
//_asm{int 3};
|
|
}
|
|
break;
|
|
case PT_BOOLEAN:
|
|
if (lpExpectedProps[PropertyIndex].Value.b != lpCompareProps[CompareIndex].Value.b) {
|
|
//bools did not match so fail compare
|
|
LUIOut(L3, "Comparison failed for prop 0x%x. Expected %u but found %u", TargetProp, lpExpectedProps[PropertyIndex].Value.b, lpCompareProps[CompareIndex].Value.b);
|
|
Result = FALSE;
|
|
}
|
|
break;
|
|
case PT_LONG:
|
|
if (lpExpectedProps[PropertyIndex].Value.l != lpCompareProps[CompareIndex].Value.l) {
|
|
//bools did not match so fail compare
|
|
LUIOut(L3, "Comparison failed for prop 0x%x. Expected %u but found %u", TargetProp, lpExpectedProps[PropertyIndex].Value.l, lpCompareProps[CompareIndex].Value.l);
|
|
Result = FALSE;
|
|
}
|
|
break;
|
|
case PT_BINARY:
|
|
if (memcmp(lpExpectedProps[PropertyIndex].Value.bin.lpb, lpCompareProps[CompareIndex].Value.bin.lpb, lpExpectedProps[PropertyIndex].Value.bin.cb)) {
|
|
//bools did not match so fail compare
|
|
LUIOut(L3, "Comparison failed for prop 0x%x. %u bytes expected, %u found and they are not equal", TargetProp, lpExpectedProps[PropertyIndex].Value.bin.cb, lpCompareProps[CompareIndex].Value.bin.cb);
|
|
Result = FALSE;
|
|
}
|
|
break;
|
|
default:
|
|
LUIOut(L3, "Unrecognized prop type 0x%x", PROP_TYPE(lpExpectedProps[PropertyIndex].ulPropTag));
|
|
} //switch
|
|
} //if propr match
|
|
} //for loop (CompareIndex)
|
|
if (!Found) {
|
|
LUIOut(L3, "Did not find property 0x%x. Compare FAILS", TargetProp);
|
|
Result = FALSE;
|
|
}
|
|
} //for loop (PropertyIndex)
|
|
//LUIOut(L3, "%u propertes compared %s", PropertyIndex, Result ? "Successfully" : "With Errors");
|
|
return(Result);
|
|
} //CompareProps()
|
|
|
|
//***
|
|
//*** Walks through the expected props until it finds the target prop and displays its value
|
|
//***
|
|
BOOL DisplayProp(SPropValue *lpSearchProps, ULONG ulTargetProp, ULONG cValues) {
|
|
BOOL Result = TRUE, Found = FALSE;
|
|
for (ULONG PropertyIndex = 0; PropertyIndex < cValues; PropertyIndex++) {
|
|
if (lpSearchProps[PropertyIndex].ulPropTag == ulTargetProp) {
|
|
//if (TargetProp == PR_DISPLAY_NAME) _asm{int 3};
|
|
Found = TRUE;
|
|
switch(PROP_TYPE(ulTargetProp)) {
|
|
case PT_STRING8:
|
|
LUIOut(L4, "Property 0x%x has value:%s", ulTargetProp, lpSearchProps[PropertyIndex].Value.LPSZ);
|
|
break;
|
|
case PT_BOOLEAN:
|
|
LUIOut(L4, "Property 0x%x has value:%i", ulTargetProp, lpSearchProps[PropertyIndex].Value.b);
|
|
break;
|
|
case PT_LONG:
|
|
LUIOut(L4, "Property 0x%x has value:0x%x", ulTargetProp, lpSearchProps[PropertyIndex].Value.l);
|
|
break;
|
|
case PT_BINARY:
|
|
LUIOut(L4, "Binary prop found but not displayed.");
|
|
break;
|
|
default:
|
|
LUIOut(L3, "Unrecognized prop type 0x%x", PROP_TYPE(ulTargetProp));
|
|
} //switch
|
|
} //if propr match
|
|
} //for loop (PropertyIndex)
|
|
if (!Found) {
|
|
LUIOut(L4, "Did not find property 0x%x.", ulTargetProp);
|
|
Result = FALSE;
|
|
}
|
|
return(Result);
|
|
} //DisplayProp()
|