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

730 lines
23 KiB

#include "pch.hxx"
#include <regutil.h>
#ifndef THOR_SETUP
#include <strconst.h>
#include "shared.h"
#else
#include "strings.h"
#include "util.h"
#endif
#include <ourguid.h>
#include <resource.h>
#ifndef THOR_SETUP
#include <shlwapi.h>
#include "shlwapip.h"
#define strstr StrStr
#define RegDeleteKeyRecursive SHDeleteKey
#endif // THOR_SETUP
#include "demand.h"
typedef HINSTANCE (STDAPICALLTYPE FGETCOMPONENTPATH)();
typedef FGETCOMPONENTPATH *LPFGETCOMPONENTPATH;
typedef HINSTANCE (STDAPICALLTYPE FIXMAPI)();
typedef FIXMAPI *LPFIXMAPI;
BOOL IsXPSP1OrLater()
{
BOOL fResult = FALSE;
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (GetVersionEx(&osvi))
{
if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
{
if (osvi.dwMajorVersion > 5)
{
fResult = TRUE;
}
else if (osvi.dwMajorVersion == 5)
{
if (osvi.dwMinorVersion > 1)
{
fResult = TRUE;
}
else if (osvi.dwMinorVersion == 1)
{
if (osvi.dwBuildNumber > 2600)
{
fResult = TRUE;
}
else if (osvi.dwBuildNumber == 2600)
{
HKEY hkey;
// HIVESFT.INF and UPDATE.INF set this for service packs:
// HKLM,SYSTEM\CurrentControlSet\Control\Windows,"CSDVersion",0x10001,0x100
LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Windows"), 0, KEY_QUERY_VALUE, &hkey);
if (ERROR_SUCCESS == lResult)
{
DWORD dwValue;
DWORD cbValue = sizeof(dwValue);
DWORD dwType;
lResult = RegQueryValueEx(hkey, TEXT("CSDVersion"), NULL, &dwType, (LPBYTE)&dwValue, &cbValue);
if ((ERROR_SUCCESS == lResult) && (REG_DWORD == dwType) && (dwValue >= 0x100))
{
fResult = TRUE;
}
RegCloseKey(hkey);
}
}
}
}
}
}
return fResult;
}
// ********* Tests
// Looks in the registry at a value placed there by msoe.dll's selfreg
BOOL GetAthenaRegPath(TCHAR *szAthenaDll, DWORD cch)
{
BOOL fRet;
HKEY hkey;
TCHAR szPath[MAX_PATH], szExpanded[MAX_PATH];
DWORD dwType, cb;
LPTSTR psz;
szPath[0] = '\0';
fRet = FALSE;
wnsprintf(szExpanded, ARRAYSIZE(szExpanded), c_szProtocolPath, c_szMail, c_szMOE);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szExpanded, 0, KEY_QUERY_VALUE, &hkey))
{
cb = sizeof(szPath);
if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szRegDllPath, 0, &dwType, (LPBYTE)szPath, &cb) && cb)
{
// Remove %values% if needed
if (REG_EXPAND_SZ == dwType)
{
ExpandEnvironmentStrings(szPath, szExpanded, ARRAYSIZE(szExpanded));
psz = szExpanded;
}
else
psz = szPath;
StrCpyN(szAthenaDll, psz, cch);
fRet = TRUE;
}
RegCloseKey(hkey);
}
return(fRet);
}
#ifdef THOR_SETUP
BOOL GetExePath(LPCTSTR szExe, TCHAR *szPath, DWORD cch, BOOL fDirOnly)
{
BOOL fRet;
HKEY hkey;
DWORD dwType, cb;
TCHAR sz[MAX_PATH], szT[MAX_PATH];
Assert(szExe != NULL);
Assert(szPath != NULL);
fRet = FALSE;
wnsprintf(sz, ARRAYSIZE(sz),c_szPathFileFmt, c_szAppPaths, szExe);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, sz, 0, KEY_QUERY_VALUE, &hkey))
{
cb = sizeof(szT);
if (ERROR_SUCCESS == RegQueryValueEx(hkey, fDirOnly ? c_szRegPath : NULL, 0, &dwType, (LPBYTE)szT, &cb) && cb)
{
if (dwType == REG_EXPAND_SZ)
{
cb = ExpandEnvironmentStrings(szT, szPath, cch);
if (cb != 0 && cb <= cch)
fRet = TRUE;
}
else
{
Assert(dwType == REG_SZ);
StrCpyN(szPath, szT, cch);
fRet = TRUE;
}
}
RegCloseKey(hkey);
}
return(fRet);
}
#endif
HRESULT GetCLSIDFromSubKey(HKEY hKey, LPSTR rgchBuf, ULONG *pcbBuf)
{
HKEY hKeyCLSID;
DWORD dwType;
HRESULT hr=E_FAIL;
// Lets open they server key
if (RegOpenKeyEx(hKey, c_szCLSID, 0, KEY_READ, &hKeyCLSID) == ERROR_SUCCESS)
{
if (ERROR_SUCCESS == RegQueryValueEx(hKeyCLSID, NULL, 0, &dwType, (LPBYTE)rgchBuf, pcbBuf) && *pcbBuf)
hr = S_OK;
RegCloseKey(hKeyCLSID);
}
return hr;
}
// FUNCTION: FAssocsOK()
//
// PURPOSE: Checks to see if our file-type associations are in place
//
// Returns:
BOOL FAssocsOK(LPCTSTR pszClient, LPCTSTR pszProduct)
{
HKEY hkeyProtocols;
HKEY hkeyRealProt;
HKEY hkeyAppsProt;
TCHAR szProtPath[MAX_PATH];
TCHAR szRealPath[MAX_PATH];
TCHAR szAppPath [MAX_PATH];
TCHAR szTemp [MAX_PATH];
DWORD dwIndex = 0;
DWORD cb;
DWORD cbMaxProtocolLen;
DWORD dwType, dwType2;
LPTSTR pszURL;
BOOL fNoProbs = TRUE;
// Open up the corresponding protocols key
wnsprintf(szProtPath, ARRAYSIZE(szProtPath), c_szProtocolPath, pszClient, pszProduct);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szProtPath, 0, KEY_READ, &hkeyProtocols))
{
// Figure out the longest protocol name
if (ERROR_SUCCESS == RegQueryInfoKey(hkeyProtocols, NULL, NULL, NULL, NULL,
&cbMaxProtocolLen, NULL, NULL, NULL, NULL, NULL, NULL))
{
// Allow for "\Shell\Open\Command" whose length is 19 + 1 for NT's RegQueryInfoKey
cbMaxProtocolLen += 20;
// Allocate buffer for string
if (MemAlloc((LPVOID*)&pszURL, cbMaxProtocolLen * sizeof(TCHAR)))
{
// Enumerate the protocol subkeys
cb = cbMaxProtocolLen;
while (fNoProbs && ERROR_SUCCESS == RegEnumKeyEx(hkeyProtocols, dwIndex++, pszURL, &cb, NULL, NULL, NULL, NULL))
{
fNoProbs = FALSE;
StrCatBuff(pszURL, c_szRegOpen, cbMaxProtocolLen);
// Open up the real protocol\shell\open\command key
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, pszURL, 0, KEY_READ, &hkeyRealProt))
{
// Open up app's protocol\shell\open\command key
if (ERROR_SUCCESS == RegOpenKeyEx(hkeyProtocols, pszURL, 0, KEY_READ, &hkeyAppsProt))
{
// Grab the current registered handler
cb = ARRAYSIZE(szRealPath);
if (ERROR_SUCCESS == RegQueryValueEx(hkeyRealProt, NULL, 0, &dwType, (LPBYTE)szRealPath, &cb))
{
// Grab the App's Path
cb = ARRAYSIZE(szAppPath);
if (ERROR_SUCCESS == RegQueryValueEx(hkeyAppsProt, NULL, 0, &dwType2, (LPBYTE)szAppPath, &cb))
{
if (REG_EXPAND_SZ == dwType2)
{
ExpandEnvironmentStrings(szAppPath, szTemp, ARRAYSIZE(szTemp));
StrCpyN(szAppPath, szTemp, ARRAYSIZE(szAppPath));
}
if (REG_EXPAND_SZ == dwType)
{
ExpandEnvironmentStrings(szRealPath, szTemp, ARRAYSIZE(szTemp));
StrCpyN(szRealPath, szTemp, ARRAYSIZE(szRealPath));
}
// Do a simple case insensitive comparison
if (!lstrcmpi(szAppPath, szRealPath))
fNoProbs = TRUE;
}
}
RegCloseKey(hkeyAppsProt);
}
RegCloseKey(hkeyRealProt);
}
// Reset cb
cb = cbMaxProtocolLen;
}
MemFree(pszURL);
}
}
RegCloseKey(hkeyProtocols);
}
return (fNoProbs);
}
// FUNCTION: FExchangeServerInstalled()
//
// PURPOSE: Checks to see if Exchange Server is installed
//
// Based on code provided by msmith from OL
//
BOOL FExchangeServerInstalled()
{
HKEY hkeyServices;
BOOL fInstalled = FALSE;
// Get HKLM\Software\Microsoft\Exchange\Setup registry key
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szExchangeSetup, 0, KEY_READ, &hkeyServices))
{
// Does Services registry value exist?
fInstalled = ERROR_SUCCESS == RegQueryValueEx(hkeyServices, c_szServices, NULL, NULL, NULL, NULL);
RegCloseKey(hkeyServices);
}
return (fInstalled);
}
// FUNCTION: FMapiStub()
//
// PURPOSE: Checks to see if the mapi32.dll is Outlook's
//
// Based on code provided by [email protected]
//
// Return Value: TRUE - all is well
// *pdw = Failure type if Return value is FALSE:
// 1 = No mapi32.dll
// 2 = Different mapi32.dll
//
BOOL FMapiStub(DWORD *pdw)
{
HINSTANCE hMapiStub;
TCHAR szSystemPath[MAX_PATH];
TCHAR szMapiPath[MAX_PATH];
BOOL fMapiStub = FALSE;
Assert(pdw);
*pdw = 0;
// If Exchange server is installed, their stub is in place, so leave it be
if (FExchangeServerInstalled())
return TRUE;
// Build a path to mapi32.dll
GetSystemDirectory(szSystemPath, ARRAYSIZE(szSystemPath));
MakeFilePath(szSystemPath, c_szMAPIDLL, c_szEmpty, szMapiPath, ARRAYSIZE(szMapiPath));
hMapiStub = LoadLibrary(szMapiPath);
if (hMapiStub)
{
fMapiStub = NULL != (LPFGETCOMPONENTPATH)GetProcAddress(hMapiStub, TEXT("FGetComponentPath")); // STRING_OK Msmith
if (!fMapiStub)
*pdw = 2;
FreeLibrary(hMapiStub);
}
else
*pdw = 1;
return fMapiStub;
}
BOOL FValidClient(LPCTSTR pszClient, LPCTSTR pszProduct)
{
TCHAR szBuffer[MAX_PATH];
HKEY hkey2;
BOOL fValid = FALSE;
wnsprintf(szBuffer, ARRAYSIZE(szBuffer), c_szRegPathSpecificClient, pszClient, pszProduct);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_QUERY_VALUE, &hkey2))
{
RegCloseKey(hkey2);
fValid = TRUE;
}
return fValid;
}
int DefaultClientSet(LPCTSTR pszClient)
{
int iRet;
TCHAR sz[MAX_PATH], sz2[MAX_PATH];
HKEY hkey, hkeyT;
DWORD dwType, cb;
iRet = NOT_HANDLED;
wnsprintf(sz, ARRAYSIZE(sz), c_szPathFileFmt, c_szRegPathClients, pszClient);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, sz, 0, KEY_QUERY_VALUE, &hkey))
{
cb = sizeof(sz);
if (ERROR_SUCCESS == RegQueryValueEx(hkey, NULL, NULL, &dwType, (LPBYTE)&sz, &cb))
{
// Sanity check - is the current client even valid?
wnsprintf(sz2, ARRAYSIZE(sz2), c_szRegPathSpecificClient, pszClient, sz);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, sz2, 0, KEY_QUERY_VALUE, &hkeyT))
{
RegCloseKey(hkeyT);
if (0 == lstrcmpi(c_szMOE, sz))
iRet = HANDLED_CURR;
else if (0 == lstrcmpi(c_szIMN, sz))
iRet = NOT_HANDLED;
else if (0 == lstrcmpi(c_szOutlook, sz))
iRet = HANDLED_OUTLOOK;
else if (0 == lstrcmpi(c_szNT, sz))
iRet = NOT_HANDLED;
else if (*sz != 0)
iRet = HANDLED_OTHER;
}
}
RegCloseKey(hkey);
}
return(iRet);
}
//
// FUNCTION: FIsDefaultNewsConfiged()
//
// PURPOSE: Determines if Athena is currently the default news handler.
//
BOOL WINAPI FIsDefaultNewsConfiged(DWORD dwFlags)
{
BOOL fRet;
if (0 == (dwFlags & DEFAULT_OUTNEWS))
fRet = (HANDLED_CURR == DefaultClientSet(c_szNews)) && FAssocsOK(c_szNews, c_szMOE);
else
fRet = (HANDLED_OUTLOOK == DefaultClientSet(c_szNews)) && FAssocsOK(c_szNews, c_szOutlook);
return(fRet);
}
//
// FUNCTION: FIsDefaultMailConfiged()
//
// PURPOSE: Determines if Athena is currently the default mail handler.
//
BOOL WINAPI FIsDefaultMailConfiged()
{
DWORD dwTemp;
return (HANDLED_CURR == DefaultClientSet(c_szMail) && FAssocsOK(c_szMail, c_szMOE) && FMapiStub(&dwTemp));
}
// ********* Actions
// Set up the URL with our handler
BOOL AddUrlHandler(LPCTSTR pszURL, LPCTSTR pszClient, LPCTSTR pszProduct, DWORD dwFlags)
{
HKEY hKey, hKeyProt;
TCHAR szBuffer[MAX_PATH], szBuffer1[MAX_PATH];
DWORD dwDisp, cb;
BOOL fCreate = TRUE;
// Try to detect if this URL is set or not...
if (dwFlags & DEFAULT_DONTFORCE)
{
DWORD dwLen = lstrlen(pszURL);
LPTSTR pszTemp;
// 20 = 19 (length of "\Shell\Open\Command") + 1 for NULL
DWORD cchSize = (dwLen+20);
if (MemAlloc((LPVOID*)&pszTemp, cchSize * sizeof(pszTemp[0])))
{
StrCpyN(pszTemp, pszURL, cchSize);
StrCatBuff(pszTemp, c_szRegOpen, cchSize);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, pszTemp, 0, KEY_READ, &hKey))
{
cb = sizeof(szBuffer);
if (ERROR_SUCCESS == RegQueryValueEx(hKey, NULL, 0, NULL, (LPBYTE)szBuffer, &cb))
{
// Special case URL.DLL and MAILNEWS.DLL as okay to overwrite
if (!strstr(szBuffer, c_szUrlDll) && !strstr(szBuffer, c_szMailNewsDllOld))
fCreate = FALSE;
}
RegCloseKey(hKey);
}
MemFree(pszTemp);
}
}
// Clear out any old info about this URL
if (fCreate)
{
RegDeleteKeyRecursive(HKEY_CLASSES_ROOT, pszURL);
// Figure out the source for the info
wnsprintf(szBuffer1, ARRAYSIZE(szBuffer1), c_szProtocolPath, pszClient, pszProduct);
wnsprintf(szBuffer, ARRAYSIZE(szBuffer), c_szPathFileFmt, szBuffer1, pszURL);
// Copy the info to its new location
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKeyProt))
{
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CLASSES_ROOT, pszURL, 0,
NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hKey, &dwDisp))
{
CopyRegistry(hKeyProt, hKey);
RegCloseKey(hKey);
}
RegCloseKey(hKeyProt);
}
}
return(TRUE);
}
void SetDefaultClient(LPCTSTR pszClient, LPCTSTR pszProduct, DWORD dwFlags)
{
TCHAR sz[MAX_PATH];
HKEY hkey;
DWORD dwDisp;
BOOL fOK = TRUE;
if (DEFAULT_DONTFORCE & dwFlags)
{
if (NOT_HANDLED != DefaultClientSet(pszClient))
fOK = FALSE;
}
if (fOK)
{
wnsprintf(sz, ARRAYSIZE(sz), c_szPathFileFmt, c_szRegPathClients, pszClient);
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, sz,
0, NULL, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, NULL, &hkey, &dwDisp))
{
RegSetValueEx(hkey, NULL, 0, REG_SZ, (LPBYTE)pszProduct,
(lstrlen(pszProduct) + 1) * sizeof(TCHAR));
#ifndef THOR_SETUP
// Bug 32136 in IE6 database
SHSendMessageBroadcast(WM_SETTINGCHANGE, 0, (LPARAM)sz);
#endif // THOR_SETUP
RegCloseKey(hkey);
}
}
}
// Make sure MAPI32.dll is really Outlook's MAPISTUB
BOOL EnsureMAPIStub(DWORD dwFlags)
{
BOOL fOK = FALSE;
DWORD dwReason, dwReason2;
HINSTANCE hMapiStub = NULL;
TCHAR szSystemPath[MAX_PATH];
TCHAR szPath[MAX_PATH];
LPFGETCOMPONENTPATH pfnFixMAPI;
HKEY hkeyRunOnce;
BOOL fUI = dwFlags & DEFAULT_UI;
UINT cch;
// Is the mapistub already in place?
if (FMapiStub(&dwReason))
{
fOK = TRUE;
goto exit;
}
switch (dwReason)
{
case 0:
AssertSz(FALSE, "EnsureMAPIStub failed for no reason.");
goto exit;
case 1: // NonExistent
case 2: // Different
// Should be able to just load mapistub and FixMAPI
// Build a path to mapistub.dll
cch = GetSystemDirectory(szSystemPath, ARRAYSIZE(szSystemPath));
if (cch && cch <= ARRAYSIZE(szSystemPath))
{
MakeFilePath(szSystemPath, c_szMAPIStub, c_szEmpty, szPath, ARRAYSIZE(szPath));
// Try to load
hMapiStub = LoadLibrary(szPath);
} // else we fall through with NULL hMapiStub to failure case
if (hMapiStub)
{
// Look for the FixMAPI function
pfnFixMAPI = (LPFIXMAPI)GetProcAddress(hMapiStub, TEXT("FixMAPI"));
if (pfnFixMAPI)
{
// Found the entry point, run it
pfnFixMAPI();
// Did that fix mapi32?
if (!FMapiStub(&dwReason2))
{
// No, maybe the old one was in use...
if (2 == dwReason)
{
// Add a runonce entry for fixmapi
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szMAPIRunOnce, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hkeyRunOnce, &dwReason))
{
// 12 = (11 + 1) where 11 is length of fixmapi.exe + 1 for the null
if (ERROR_SUCCESS == RegSetValueEx(hkeyRunOnce, c_szMAPIRunOnceEntry, 0, REG_SZ, (LPBYTE)c_szFixMAPI, 12 * sizeof(TCHAR)))
{
#ifndef THOR_SETUP
// Tell the user to reboot
if (fUI)
AthMessageBoxW(GetDesktopWindow(), MAKEINTRESOURCEW(idsSimpleMAPI), MAKEINTRESOURCEW(idsMAPISTUBNeedsReboot), NULL, MB_OK);
#endif
// Probable success
fOK = TRUE;
}
RegCloseKey(hkeyRunOnce);
}
}
else
{
#ifndef THOR_SETUP
if (fUI)
AthMessageBoxW(GetDesktopWindow(), MAKEINTRESOURCEW(idsSimpleMAPI), MAKEINTRESOURCEW(idsMAPISTUBFailed), NULL, MB_OK);
#endif
}
}
else
// Success!
fOK = TRUE;
}
// Eek, where is FixMAPI?
else
{
#ifndef THOR_SETUP
if (fUI)
AthMessageBoxW(GetDesktopWindow(), MAKEINTRESOURCEW(idsSimpleMAPI), MAKEINTRESOURCEW(idsMAPISTUBMissingExport), NULL, MB_OK);
#endif
}
FreeLibrary(hMapiStub);
}
else
{
// Dll missing or unloadable
#ifndef THOR_SETUP
if (fUI)
AthMessageBoxW(GetDesktopWindow(), MAKEINTRESOURCEW(idsSimpleMAPI), MAKEINTRESOURCEW(idsMAPISTUBNoLoad), NULL, MB_OK);
#endif
}
break;
default:
AssertSz(FALSE, "EnsureMAPIStub returned an unknown failure. Bailing");
goto exit;
}
exit:
return fOK;
}
// Change the Default News handler
HRESULT ISetDefaultNewsHandler(LPCTSTR pszProduct, DWORD dwFlags)
{
AddUrlHandler(c_szURLNews, c_szNews, pszProduct, dwFlags);
AddUrlHandler(c_szURLNNTP, c_szNews, pszProduct, dwFlags);
AddUrlHandler(c_szURLSnews, c_szNews, pszProduct, dwFlags);
SetDefaultClient(c_szNews, pszProduct, dwFlags);
return (S_OK);
}
// Change the Default Mail handler
HRESULT ISetDefaultMailHandler(LPCTSTR pszProduct, DWORD dwFlags)
{
// May change default handler to owner of mapi32.dll
EnsureMAPIStub(dwFlags);
AddUrlHandler(c_szURLMailTo, c_szMail, pszProduct, dwFlags);
if ((dwFlags & DEFAULT_SETUPMODE) && IsXPSP1OrLater())
{
// running setup50.exe on XPSP1 or later, let OE Access handle it from here.
}
else
{
// Non setup50.exe case (like "would you like to make OE your default mail client?")
// or we're running downlevel -- go ahead and do it.
SetDefaultClient(c_szMail, pszProduct, dwFlags);
}
return (S_OK);
}
//
// FUNCTION: SetDefaultMailHandler()
//
// PURPOSE: Adds the keys to the registry to make Athena the user's
// default mail reader.
//
// RETURN VALUE:
// HRESULT
//
// ATTENZIONE! if you change the parameters for this function, make sure
// that you make the proper change to athena\msoeacct\silent.cpp (it calls
// this via GetProcAddress)
HRESULT WINAPI SetDefaultMailHandler(DWORD dwFlags)
{
return ISetDefaultMailHandler(c_szMOE, dwFlags | DEFAULT_MAIL);
}
//
// FUNCTION: SetDefaultNewsHandler()
//
// PURPOSE: Adds the keys to the registry to make Athena the user's
// default news reader.
//
// RETURN VALUE:
// HRESULT
//
// ATTENZIONE! if you change the parameters for this function, make sure
// that you make the proper change to athena\msoeacct\silent.cpp (it calls
// this via GetProcAddress)
HRESULT WINAPI SetDefaultNewsHandler(DWORD dwFlags)
{
if (dwFlags & DEFAULT_OUTNEWS)
return ISetDefaultNewsHandler(c_szOutlook, dwFlags);
else
return ISetDefaultNewsHandler(c_szMOE, dwFlags | DEFAULT_NEWS);
}