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.
384 lines
13 KiB
384 lines
13 KiB
/**********************************************************************************
|
|
*
|
|
*
|
|
* ui_ext.C - contains functions for handling/creating the extension property
|
|
* sheets to the wab property sheets
|
|
*
|
|
* Created - 9/97 - vikramm
|
|
*
|
|
**********************************************************************************/
|
|
#include "_apipch.h"
|
|
|
|
static const TCHAR szExtDisplayMailUser[] = TEXT("Software\\Microsoft\\WAB\\WAB4\\ExtDisplay\\MailUser");
|
|
static const TCHAR szExtDisplayDistList[] = TEXT("Software\\Microsoft\\WAB\\WAB4\\ExtDisplay\\DistList");
|
|
|
|
DEFINE_GUID(CLSID_DsPropertyPages,
|
|
0xd45d530, 0x764b, 0x11d0, 0xa1, 0xca, 0x0, 0xaa, 0x0, 0xc1, 0x6e, 0x65);
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddPropSheetPageProc
|
|
//
|
|
// CallBack from the Extension Sheets Prop Sheet creation function
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CALLBACK AddPropSheetPageProc( HPROPSHEETPAGE hpage, LPARAM lParam )
|
|
{
|
|
LPPROP_ARRAY_INFO lpPropArrayInfo = (LPPROP_ARRAY_INFO) lParam;
|
|
HPROPSHEETPAGE * lphTemp = NULL;
|
|
int i = 0;
|
|
BOOL bNTDSExt = IsEqualGUID(&lpPropArrayInfo->guidExt, &CLSID_DsPropertyPages); //special casing for NTDS extensions
|
|
int nPages = bNTDSExt ? lpPropArrayInfo->nNTDSPropSheetPages : lpPropArrayInfo->nPropSheetPages;
|
|
HPROPSHEETPAGE * lph = bNTDSExt ? lpPropArrayInfo->lphNTDSpages : lpPropArrayInfo->lphpages;
|
|
|
|
if(!hpage)
|
|
return FALSE;
|
|
|
|
// Grow the lpPropArrayInfo->lphpages array
|
|
lphTemp = LocalAlloc(LMEM_ZEROINIT, sizeof(HPROPSHEETPAGE) * (nPages+1));
|
|
if(!lphTemp)
|
|
return FALSE;
|
|
|
|
// really inefficient
|
|
if(lph)
|
|
{
|
|
for(i=0;i<nPages;i++)
|
|
{
|
|
lphTemp[i] = lph[i];
|
|
}
|
|
LocalFree(lph);
|
|
}
|
|
if(bNTDSExt)
|
|
{
|
|
lpPropArrayInfo->lphNTDSpages = lphTemp;
|
|
lpPropArrayInfo->lphNTDSpages[lpPropArrayInfo->nNTDSPropSheetPages] = hpage;
|
|
lpPropArrayInfo->nNTDSPropSheetPages++;
|
|
}
|
|
else
|
|
{
|
|
lpPropArrayInfo->lphpages = lphTemp;
|
|
lpPropArrayInfo->lphpages[lpPropArrayInfo->nPropSheetPages] = hpage;
|
|
lpPropArrayInfo->nPropSheetPages++;
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//$$////////////////////////////////////////////////////////////////////
|
|
//
|
|
// HrGetExtDLLInfo
|
|
//
|
|
// Enumerate all the registered DLL names and Function procs from the
|
|
// registry
|
|
//
|
|
// bMailUser - if true, look for mailuser extensions
|
|
// - if false, look for distlist extensions
|
|
////////////////////////////////////////////////////////////////////////
|
|
HRESULT HrGetExtDLLInfo(LPEXTDLLINFO * lppList, ULONG * lpulCount, BOOL bMailUser, LPGUID lpguidPSExt)
|
|
{
|
|
|
|
HRESULT hr = E_FAIL;
|
|
HKEY hKey = NULL;
|
|
DWORD dwIndex = 0, dwSize = 0;
|
|
LPTSTR lpReg = NULL;
|
|
LPEXTDLLINFO lpList = NULL;
|
|
ULONG ulCount = 0;
|
|
|
|
if(!lppList || !lpulCount)
|
|
goto out;
|
|
|
|
*lppList = NULL;
|
|
*lpulCount = 0;
|
|
|
|
lpReg = (LPTSTR) (bMailUser ? szExtDisplayMailUser : szExtDisplayDistList);
|
|
|
|
if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
lpReg,
|
|
0, KEY_READ,
|
|
&hKey))
|
|
{
|
|
goto out;
|
|
}
|
|
|
|
|
|
{
|
|
TCHAR szGUIDName[MAX_PATH];
|
|
DWORD dwGUIDIndex = 0, dwGUIDSize = CharSizeOf(szGUIDName), dwType = 0;
|
|
|
|
*szGUIDName = '\0';
|
|
|
|
while(ERROR_SUCCESS == RegEnumValue(hKey, dwGUIDIndex,
|
|
szGUIDName, &dwGUIDSize,
|
|
0, &dwType,
|
|
NULL, NULL))
|
|
{
|
|
// The values under this entry are all GUIDs
|
|
// Read the GUID string and translate it into a GUID
|
|
//
|
|
GUID guidTmp = {0};
|
|
WCHAR szW[MAX_PATH];
|
|
StrCpyN(szW, szGUIDName, ARRAYSIZE(szW));
|
|
if( lstrlen(szW) && !(HR_FAILED(hr = CLSIDFromString(szW, &guidTmp))) )
|
|
{
|
|
// Some applications may not want to see their property sheet extensions displayed
|
|
// unless they have invoked the WAB. These applications can provide a GUID identifying
|
|
// them which will be compared to the extension GUIDs. If the GUID has a Data Value of
|
|
// "1" this means it should only be loaded on-demand ..
|
|
|
|
// First check the data Value
|
|
TCHAR sz[32];
|
|
DWORD dw = CharSizeOf(sz), dwT = 0;
|
|
if(ERROR_SUCCESS == RegQueryValueEx(hKey, szGUIDName, NULL, &dwT, (LPBYTE) sz, &dw))
|
|
{
|
|
if( !lstrcmpi(sz, TEXT("1")) // this one wants to be loaded on demand only
|
|
&& memcmp(&guidTmp, lpguidPSExt, sizeof(GUID)) ) //but guid doesnt match
|
|
{
|
|
goto endwhile;
|
|
}
|
|
}
|
|
{
|
|
LPEXTDLLINFO lpTemp = LocalAlloc(LMEM_ZEROINIT, sizeof(EXTDLLINFO));
|
|
if(!lpTemp)
|
|
{
|
|
hr = MAPI_E_NOT_ENOUGH_MEMORY;
|
|
goto out;
|
|
}
|
|
CopyMemory(&(lpTemp->guidPropExt), &guidTmp, sizeof(GUID));
|
|
lpTemp->bMailUser = bMailUser;
|
|
lpTemp->lpNext = lpList;
|
|
lpList = lpTemp;
|
|
ulCount++;
|
|
}
|
|
}
|
|
endwhile:
|
|
dwGUIDIndex++;
|
|
*szGUIDName = '\0';
|
|
dwGUIDSize = CharSizeOf(szGUIDName);
|
|
}
|
|
}
|
|
|
|
*lppList = lpList;
|
|
*lpulCount = ulCount;
|
|
hr = S_OK;
|
|
out:
|
|
if(hKey)
|
|
RegCloseKey(hKey);
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL fPropExtCoinit = FALSE;
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// UninitExtInfo
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void UninitExtInfo()
|
|
{
|
|
if(fPropExtCoinit)
|
|
{
|
|
CoUninitialize();
|
|
fPropExtCoinit = FALSE;
|
|
}
|
|
}
|
|
|
|
//$$///////////////////////////////////////////////////////////////////
|
|
//
|
|
// FreePropExtList
|
|
//
|
|
///////////////////////////////////////////////////////////////////////
|
|
void FreePropExtList(LPEXTDLLINFO lpList)
|
|
{
|
|
LPEXTDLLINFO lpTemp = lpList;
|
|
while(lpList)
|
|
{
|
|
lpList = lpTemp->lpNext;
|
|
SafeRelease(lpTemp->lpWABExtInit);
|
|
SafeRelease(lpTemp->lpPropSheetExt);
|
|
LocalFree(lpTemp);
|
|
lpTemp = lpList;
|
|
}
|
|
}
|
|
|
|
//$$///////////////////////////////////////////////////////////////////
|
|
//
|
|
// GetExtDisplayInfo
|
|
//
|
|
// Gets all the requisite info for the extended property pages
|
|
//
|
|
// fReadOnly - specifies if all prop sheet controls should be readonly
|
|
// fMailUser - true for contact, false for group
|
|
//
|
|
///////////////////////////////////////////////////////////////////////
|
|
HRESULT GetExtDisplayInfo(LPIAB lpIAB,
|
|
LPPROP_ARRAY_INFO lpPropArrayInfo,
|
|
BOOL fReadOnly,
|
|
BOOL bMailUser)
|
|
{
|
|
ULONG i=0, nDLLs = 0;
|
|
HRESULT hr = E_FAIL;
|
|
LPEXTDLLINFO lpList = NULL, lpDLL = NULL;
|
|
|
|
if(!lpIAB->lpPropExtDllList)
|
|
{
|
|
// There can be seperate registered entries for MailUsers and for DistLists
|
|
// We will read everything and collate it into 1 large list
|
|
|
|
LPEXTDLLINFO lpListMU = NULL, lpListDL = NULL;
|
|
ULONG nDllsMU = 0, nDllsDL = 0;
|
|
HRESULT hrMU = S_OK, hrDL = S_OK;
|
|
|
|
// Get the list of registered DLL names for MailUsers
|
|
//
|
|
hrMU = HrGetExtDLLInfo(&lpListMU, &nDllsMU, TRUE, &lpIAB->guidPSExt);
|
|
hrDL = HrGetExtDLLInfo(&lpListDL, &nDllsDL, FALSE, &lpIAB->guidPSExt);
|
|
|
|
if( (!lpListMU && !lpListDL) ||
|
|
!(nDllsDL + nDllsMU) ||
|
|
(HR_FAILED(hrMU) && HR_FAILED(hrDL)) )
|
|
{
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
if(lpListMU)
|
|
{
|
|
lpIAB->lpPropExtDllList = lpListMU;
|
|
while(lpListMU->lpNext)
|
|
lpListMU = lpListMU->lpNext;
|
|
lpListMU->lpNext = lpListDL;
|
|
}
|
|
else
|
|
lpIAB->lpPropExtDllList = lpListDL;
|
|
|
|
lpIAB->nPropExtDLLs = nDllsDL + nDllsMU;
|
|
}
|
|
|
|
lpList = lpIAB->lpPropExtDllList;
|
|
nDLLs = lpIAB->nPropExtDLLs;
|
|
|
|
lpPropArrayInfo->lpWED = LocalAlloc(LMEM_ZEROINIT, sizeof(WABEXTDISPLAY));
|
|
if(!lpPropArrayInfo->lpWED)
|
|
{
|
|
hr = MAPI_E_NOT_ENOUGH_MEMORY;
|
|
goto out;
|
|
}
|
|
|
|
lpPropArrayInfo->lpWED->lpWABObject = (LPWABOBJECT) ((LPIAB)lpPropArrayInfo->lpIAB)->lpWABObject;
|
|
lpPropArrayInfo->lpWED->lpAdrBook = lpPropArrayInfo->lpIAB;
|
|
lpPropArrayInfo->lpWED->lpPropObj = lpPropArrayInfo->lpPropObj;
|
|
lpPropArrayInfo->lpWED->fReadOnly = fReadOnly;
|
|
lpPropArrayInfo->lpWED->fDataChanged = FALSE;
|
|
|
|
if(lpPropArrayInfo->lpLDAPURL && lstrlen(lpPropArrayInfo->lpLDAPURL))
|
|
{
|
|
lpPropArrayInfo->lpWED->ulFlags |= WAB_DISPLAY_LDAPURL;
|
|
lpPropArrayInfo->lpWED->lpsz = lpPropArrayInfo->lpLDAPURL;
|
|
lpPropArrayInfo->lpWED->ulFlags |= MAPI_UNICODE;
|
|
if(lpPropArrayInfo->bIsNTDSURL)
|
|
lpPropArrayInfo->lpWED->ulFlags |= WAB_DISPLAY_ISNTDS;
|
|
}
|
|
|
|
if (CoInitialize(NULL) == S_FALSE)
|
|
{
|
|
CoUninitialize(); // Already initialized, undo the extra.
|
|
}
|
|
else
|
|
fPropExtCoinit = TRUE;
|
|
|
|
lpDLL = lpList;
|
|
for(i=0;i<nDLLs;i++)
|
|
{
|
|
if(lpDLL)
|
|
{
|
|
if(lpDLL->bMailUser==bMailUser)
|
|
{
|
|
if(!lpDLL->lpPropSheetExt || !lpDLL->lpWABExtInit)
|
|
{
|
|
LPSHELLPROPSHEETEXT lpShellPropSheetExt = NULL;
|
|
|
|
hr = CoCreateInstance( &(lpDLL->guidPropExt),
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
|
|
&IID_IShellPropSheetExt,
|
|
(LPVOID *)&(lpDLL->lpPropSheetExt));
|
|
if(lpDLL->lpPropSheetExt && !HR_FAILED(hr))
|
|
{
|
|
hr = lpDLL->lpPropSheetExt->lpVtbl->QueryInterface(lpDLL->lpPropSheetExt,
|
|
&IID_IWABExtInit,
|
|
(LPVOID *)&(lpDLL->lpWABExtInit));
|
|
if(HR_FAILED(hr) || !lpDLL->lpWABExtInit)
|
|
{
|
|
SafeRelease(lpDLL->lpPropSheetExt);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(lpDLL->lpPropSheetExt && lpDLL->lpWABExtInit)
|
|
{
|
|
lpPropArrayInfo->guidExt = lpDLL->guidPropExt;
|
|
|
|
hr = lpDLL->lpWABExtInit->lpVtbl->Initialize( lpDLL->lpWABExtInit,
|
|
lpPropArrayInfo->lpWED);
|
|
if(!HR_FAILED(hr))
|
|
{
|
|
hr = lpDLL->lpPropSheetExt->lpVtbl->AddPages(lpDLL->lpPropSheetExt,
|
|
&AddPropSheetPageProc,
|
|
(LPARAM) lpPropArrayInfo);
|
|
}
|
|
}
|
|
}
|
|
lpDLL = lpDLL->lpNext;
|
|
}
|
|
}
|
|
|
|
//lpPropArrayInfo->lpExtList = lpList;
|
|
lpList = NULL;
|
|
|
|
hr = S_OK;
|
|
|
|
out:
|
|
if(lpList)
|
|
FreePropExtList(lpList);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FreeExtDisplayInfo
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void FreeExtDisplayInfo(LPPROP_ARRAY_INFO lpPropArrayInfo)
|
|
{
|
|
if(lpPropArrayInfo->lpExtList)
|
|
FreePropExtList(lpPropArrayInfo->lpExtList);
|
|
if(lpPropArrayInfo->lpWED)
|
|
LocalFree(lpPropArrayInfo->lpWED);
|
|
if(lpPropArrayInfo->lphpages)
|
|
LocalFree(lpPropArrayInfo->lphpages);
|
|
//UninitExtInfo();
|
|
return;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ChangedExtDisplayInfo
|
|
//
|
|
// Returns true if the info changed on any of the prop sheets
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////
|
|
BOOL ChangedExtDisplayInfo(LPPROP_ARRAY_INFO lpPropArrayInfo, BOOL bChanged)
|
|
{
|
|
if(lpPropArrayInfo->lpWED && lpPropArrayInfo->lpWED->fDataChanged)
|
|
return TRUE;
|
|
return bChanged;
|
|
}
|
|
|
|
|