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.
 
 
 
 
 
 

541 lines
16 KiB

/*
* f r n t b o d y . c p p
*
* Purpose:
* Implementation of CFrontBody object. Derives from CBody to host the trident
* control.
*
* History
* April '97: erican - created
*
* Copyright (C) Microsoft Corp. 1995, 1996, 1997.
*/
#include <pch.hxx>
#include <wininet.h>
#include <resource.h>
#include "strconst.h"
#include "xpcomm.h"
#include "browser.h"
#include "frntbody.h"
#include <wininet.h>
#include <mshtml.h>
#include <goptions.h>
#include <thormsgs.h>
#include <spoolapi.h>
#include <notify.h>
#include <shlwapi.h>
#include <shlwapip.h>
#include "url.h"
#include "bodyutil.h"
#include "mimeutil.h"
#include "instance.h"
#include "storutil.h"
#include "demand.h"
#include "menures.h"
#include "multiusr.h"
#include "htmlhelp.h"
#include "shared.h"
#include "oetag.h"
#include "subscr.h"
#define IsBrowserMode() ( g_dwBrowserFlags & 0x07 )
CFrontBody::CFrontBody(FOLDERTYPE ftType, IAthenaBrowser *pBrowser) : CMimeEditDocHost( /*MEBF_NOSCROLL*/ 0) //$27661: turn off noscroll
{
if (pBrowser)
{
m_pBrowser = pBrowser;
m_pBrowser->AddRef();
}
m_phlbc = NULL;
m_hwndOwner = NULL;
m_pTag = 0;
m_fOEFrontPage = TRUE;
}
CFrontBody::~CFrontBody()
{
if (m_pTag)
{
m_pTag->OnFrontPageClose();
m_pTag->Release();
m_pTag = NULL;
}
SafeRelease(m_pBrowser);
SafeRelease(m_phlbc);
}
////////////////////////////////////////////////////////////////////////
//
// IUnknown
//
////////////////////////////////////////////////////////////////////////
HRESULT CFrontBody::QueryInterface(REFIID riid, LPVOID FAR *lplpObj)
{
if (!lplpObj)
return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IHlinkFrame))
{
*lplpObj = (IHlinkFrame *)this;
AddRef();
return NOERROR;
}
if (IsEqualIID(riid, IID_IServiceProvider))
{
*lplpObj = (IServiceProvider *)this;
AddRef();
return NOERROR;
}
if (IsEqualIID(riid, IID_IElementBehaviorFactory))
{
*lplpObj = (IElementBehaviorFactory *)this;
AddRef();
return NOERROR;
}
return CMimeEditDocHost::QueryInterface(riid, lplpObj);
}
ULONG CFrontBody::AddRef()
{
return CMimeEditDocHost::AddRef();
}
ULONG CFrontBody::Release()
{
return CMimeEditDocHost::Release();
}
////////////////////////////////////////////////////////////////////////
//
// IHlinkFrame
//
////////////////////////////////////////////////////////////////////////
HRESULT CFrontBody::SetBrowseContext(LPHLINKBROWSECONTEXT phlbc)
{
ReplaceInterface(m_phlbc, phlbc);
return NOERROR;
}
HRESULT CFrontBody::GetBrowseContext(LPHLINKBROWSECONTEXT *pphlbc)
{
if (pphlbc == NULL)
return E_INVALIDARG;
*pphlbc = m_phlbc;
if (m_phlbc)
m_phlbc->AddRef();
return NOERROR;
}
static const struct {
LPCWSTR pwszCmd;
UINT uCmd;
} s_rgCmdLookup[] =
{
{ L"readMail", ID_GO_INBOX },
{ L"newMessage", ID_NEW_MSG_DEFAULT },
{ L"readNews", ID_GO_NEWS },
{ L"subscribeNews", ID_NEWSGROUPS },
{ L"addrBook", ID_ADDRESS_BOOK },
{ L"findAddr", ID_FIND_PEOPLE },
{ L"newNewsAccount", ID_CREATE_NEWS_ACCOUNT },
{ L"newMailAccount", ID_CREATE_MAIL_ACCOUNT },
{ L"help", ID_HELP_CONTENTS},
{ L"newNewsMessage", ID_NEW_NEWS_MESSAGE},
{ L"newUser", ID_NEW_IDENTITY},
{ L"switchUser", ID_SWITCH_IDENTITY},
{ L"noop", ID_NOOP},
{ L"findMessage", ID_FIND_MESSAGE},
{ L"logoff", ID_LOGOFF_IDENTITY},
{ L"manageUser", ID_MANAGE_IDENTITIES},
};
HRESULT CFrontBody::Navigate(DWORD grfHLNF, LPBC pbc, LPBINDSTATUSCALLBACK pbsc, LPHLINK phlNavigate)
{
HRESULT hr;
LPWSTR pwszURL = NULL,
pwszCmd = NULL;
HINSTANCE hInst;
WCHAR wsz[CCHMAX_STRINGRES],
wszErr[CCHMAX_STRINGRES+INTERNET_MAX_URL_LENGTH+1];
CStringParser sp;
IF_FAILEXIT(hr = phlNavigate->GetStringReference(HLINKGETREF_ABSOLUTE, &pwszURL, NULL));
if (pwszURL)
{
if (!StrCmpNIW(pwszURL, L"oecmd:", 6))
{
pwszCmd = pwszURL + 6;
for (int i = 0; i < ARRAYSIZE(s_rgCmdLookup); i++)
{
if (!StrCmpNIW(pwszCmd, s_rgCmdLookup[i].pwszCmd, lstrlenW(s_rgCmdLookup[i].pwszCmd)))
{
switch (s_rgCmdLookup[i].uCmd)
{
case ID_HELP_CONTENTS:
{
LPSTR pszCmd = NULL;
pwszCmd += ARRAYSIZE(s_rgCmdLookup[i].pwszCmd);
IF_NULLEXIT(pszCmd = PszToANSI(CP_ACP, pwszCmd));
sp.Init(pszCmd, lstrlen(pszCmd), 0);
sp.ChParse("(");
sp.ChParse(")");
OEHtmlHelp(GetTopMostParent(m_hwnd), c_szCtxHelpFileHTML, HH_DISPLAY_TOPIC, (DWORD_PTR) (sp.CchValue() ? sp.PszValue() : NULL));
MemFree(pszCmd);
break;
}
case ID_CREATE_MAIL_ACCOUNT:
case ID_CREATE_NEWS_ACCOUNT:
_CreateNewAccount(s_rgCmdLookup[i].uCmd == ID_CREATE_MAIL_ACCOUNT);
// handle account creation internally
break;
default:
PostMessage(m_hwndOwner, WM_COMMAND, s_rgCmdLookup[i].uCmd, 0L);
}
SetStatusText(NULL);
hr = S_OK;
goto exit;
}
}
AssertSz(0, "Navigation request to unknown oecmd link");
hr = E_FAIL;
}
else
{
LPSTR pszURL = NULL;
TCHAR sz[CCHMAX_STRINGRES],
szErr[CCHMAX_STRINGRES+INTERNET_MAX_URL_LENGTH+1];
IF_NULLEXIT(pszURL = PszToANSI(CP_ACP, pwszURL));
hInst = ShellExecute(m_hwndOwner, NULL, pszURL, NULL, NULL, SW_SHOW);
if (hInst <= (HINSTANCE)HINSTANCE_ERROR)
{
LoadString(g_hLocRes, idsErrURLExec, sz, ARRAYSIZE(sz));
wnsprintf(szErr, ARRAYSIZE(szErr), sz, pszURL);
// load title into wsz. We don't use AthMsgBox as our string maybe too long. AthMsgBox
// will truncate at CCHMAX_STRINGRES.
LoadString(g_hLocRes, idsAthena, sz, ARRAYSIZE(sz));
MessageBox(m_hwndOwner, szErr, sz, MB_OK);
}
MemFree(pszURL);
}
}
exit:
if (pwszURL)
CoTaskMemFree(pwszURL);
return hr;
}
HRESULT CFrontBody::OnNavigate(DWORD grfHLNF, LPMONIKER pmkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
{
return E_NOTIMPL;
}
HRESULT CFrontBody::UpdateHlink(ULONG uHLID, LPMONIKER pmkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
{
return E_NOTIMPL;
}
////////////////////////////////////////////////////////////////////////
//
// IServiceProvider
//
////////////////////////////////////////////////////////////////////////
HRESULT CFrontBody::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
{
if (IsEqualGUID(guidService, IID_IHlinkFrame))
return QueryInterface(riid, ppvObject);
if (IsEqualGUID(guidService, IID_IHlinkFrame))
return QueryInterface(riid, ppvObject);
if (IsEqualGUID(guidService, SID_SElementBehaviorFactory))
return QueryInterface(riid, ppvObject);
return E_NOINTERFACE;
}
////////////////////////////////////////////////////////////////////////
//
// CDocHost
//
////////////////////////////////////////////////////////////////////////
void CFrontBody::OnDocumentReady()
{
URLSUB rgUrlSub[] = {
{ "msnlink", idsHelpMSWebHome }
};
// turn on link-tabbing for the front-page
if (m_pCmdTarget)
{
VARIANTARG va;
va.vt = VT_BOOL;
va.boolVal = VARIANT_TRUE;
m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_TABLINKS, 0, &va, NULL);
}
// #42164
// we defer-show the OE-front page via script. If an IEAK person overrides this
// with a custom front-page, then we show as soon as we go document ready
if (!m_fOEFrontPage)
HrShow(TRUE);
else
{
// if is is the std. OE page, then replace URL's
SubstituteURLs(m_pDoc, rgUrlSub, ARRAYSIZE(rgUrlSub));
}
}
////////////////////////////////////////////////////////////////////////
//
// PUBLIC
//
////////////////////////////////////////////////////////////////////////
HRESULT CFrontBody::HrInit(HWND hwnd)
{
m_hwndOwner = hwnd;
return CMimeEditDocHost::HrInit(hwnd, IBOF_TABLINKS, NULL);
}
HRESULT CFrontBody::HrLoadPage()
{
HRESULT hr = S_OK;
// bobn: brianv says we have to take this out...
/*if (IsBrowserMode())
{
hr = HrLoadURL("res://msoeres.dll/example.eml");
m_fOEFrontPage = FALSE;
g_dwBrowserFlags = 0;
}
else*/
{
DWORD cbData;
TCHAR szURL[INTERNET_MAX_URL_LENGTH + 1];
TCHAR *pszUrl;
LPSTR pszUrlFree=NULL;
*szURL = 0;
cbData = sizeof(szURL);
AthUserGetValue(NULL, c_szFrontPagePath, NULL, (LPBYTE)szURL, &cbData);
if (*szURL)
{
pszUrl = szURL;
m_fOEFrontPage = FALSE;
}
else
{
pszUrlFree = PszAllocResUrl(g_dwAthenaMode & MODE_NEWSONLY ? "frntnews.htm" : "frntpage.htm");
pszUrl = pszUrlFree;
}
hr = HrLoadURL(pszUrl);
SafeMemFree(pszUrlFree);
}
return hr;
}
HRESULT CFrontBody::SetStatusText(LPCOLESTR pszW)
{
WCHAR wszRes[CCHMAX_STRINGRES];
LPWSTR pszStatusW=0;
HRESULT hr;
if (pszW && !StrCmpNIW(pszW, L"oecmd:", 6))
{
for (int i = 0; i < ARRAYSIZE(s_rgCmdLookup); i++)
{
if (!StrCmpNIW(pszW+6, s_rgCmdLookup[i].pwszCmd, lstrlenW(s_rgCmdLookup[i].pwszCmd)))
{
*wszRes = 0;
LoadStringWrapW(g_hLocRes, MH(s_rgCmdLookup[i].uCmd), wszRes, ARRAYSIZE(wszRes));
// If this fails, worse that happens is that the status text is nulled.
pszStatusW = PszDupW(wszRes);
pszW = pszStatusW;
break;
}
}
}
hr = CMimeEditDocHost::SetStatusText(pszW);
MemFree(pszStatusW);
return hr;
}
HRESULT CFrontBody::_CreateNewAccount(BOOL fMail)
{
IImnAccount *pAcct=0,
*pAcctDef;
FOLDERID id;
DWORD dwServer=0;
CHAR rgch[CCHMAX_ACCOUNT_NAME];
HRESULT hr;
DWORD dwPropGet,
dwPropSet;
// create a new account object
hr = g_pAcctMan->CreateAccountObject(fMail ? ACCT_MAIL : ACCT_NEWS, &pAcct);
if (FAILED(hr))
{
TraceResult(hr);
goto exit;
}
// If creating a new news account, try and use default-mail information. If creating a new mail account, try
// and use default-news information (if any). We don't use def-mail for mail accounts as the front-page only shows
// links for account-creation if there are 0 accounts of that type.
if (g_pAcctMan->GetDefaultAccount(fMail ? ACCT_NEWS : ACCT_MAIL, &pAcctDef)==S_OK)
{
dwPropGet = fMail ? AP_NNTP_DISPLAY_NAME : AP_SMTP_DISPLAY_NAME;
dwPropSet = fMail ? AP_SMTP_DISPLAY_NAME : AP_NNTP_DISPLAY_NAME;
if (pAcctDef->GetPropSz(dwPropGet, rgch, ARRAYSIZE(rgch))==S_OK)
pAcct->SetPropSz(dwPropSet, rgch);
dwPropGet = fMail ? AP_NNTP_EMAIL_ADDRESS : AP_SMTP_EMAIL_ADDRESS;
dwPropSet = fMail ? AP_SMTP_EMAIL_ADDRESS : AP_NNTP_EMAIL_ADDRESS;
if (pAcctDef->GetPropSz(dwPropGet, rgch, ARRAYSIZE(rgch))==S_OK)
pAcct->SetPropSz(dwPropSet, rgch);
pAcctDef->Release();
}
// show the account wizard dialog and allow the user to setup properties
hr = pAcct->DoWizard(m_hwndOwner, ACCT_WIZ_MIGRATE | ACCT_WIZ_INTERNETCONNECTION |
ACCT_WIZ_HTTPMAIL | ACCT_WIZ_OE);
if (FAILED(hr))
{
TraceResult(hr);
goto exit;
}
// find out what servers were added
hr = pAcct->GetServerTypes(&dwServer);
if (FAILED(hr))
{
TraceResult(hr);
goto exit;
}
// if we added a new news or IMAP account, ask the user if they want to see the subscription dialog
if ( ((dwServer & SRV_IMAP) || (dwServer & SRV_NNTP)) &&
IDYES == AthMessageBoxW(m_hwndOwner, MAKEINTRESOURCEW(idsAthena),
dwServer & SRV_NNTP ? MAKEINTRESOURCEW(idsDisplayNewsSubDlg) : MAKEINTRESOURCEW(idsDisplayImapSubDlg),
0, MB_ICONEXCLAMATION | MB_YESNO))
{
// get the account-id
hr = pAcct->GetPropSz(AP_ACCOUNT_ID, rgch, ARRAYSIZE(rgch));
if (FAILED(hr))
{
TraceResult(hr);
goto exit;
}
// find the associated node in the store
hr = g_pStore->FindServerId(rgch, &id);
if (FAILED(hr))
{
TraceResult(hr);
goto exit;
}
//The user wants to download the list of newsgroups, so if we are offline, go online
if (g_pConMan)
g_pConMan->SetGlobalOffline(FALSE);
// finally, show the subscription dialog
DoSubscriptionDialog(m_hwndOwner, dwServer & SRV_NNTP, id);
}
exit:
ReleaseObj(pAcct);
return hr;
}
HRESULT CFrontBody::HrClose()
{
if (m_pTag)
{
m_pTag->OnFrontPageClose();
m_pTag->Release();
m_pTag = NULL;
}
SafeRelease(m_pBrowser);
return CMimeEditDocHost::HrClose();
}
HRESULT CFrontBody::FindBehavior(LPOLESTR pchBehavior, LPOLESTR pchBehaviorUrl, IElementBehaviorSite* pSite, IElementBehavior** ppBehavior)
{
HRESULT hr;
if ((StrCmpIW(pchBehavior, L"APPLICATION")==0 && StrCmpIW(pchBehaviorUrl, L"#DEFAULT#APPLICATION")==0))
{
if (!m_pTag)
{
m_pTag = new COETag(m_pBrowser, this);
if (!m_pTag)
return E_OUTOFMEMORY;
}
return m_pTag->QueryInterface(IID_IElementBehavior, (LPVOID *)ppBehavior);
}
return E_FAIL;
}
HRESULT CFrontBody::GetHostInfo( DOCHOSTUIINFO* pInfo )
{
pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
pInfo->dwFlags = DOCHOSTUIFLAG_DIV_BLOCKDEFAULT|DOCHOSTUIFLAG_OPENNEWWIN|
DOCHOSTUIFLAG_NO3DBORDER|DOCHOSTUIFLAG_CODEPAGELINKEDFONTS;
//This sets the flags that match the browser's encoding
fGetBrowserUrlEncoding(&pInfo->dwFlags);
// bobn: brianv says we have to take this out...
/*if (IsBrowserMode())
pInfo->dwFlags |= DOCHOSTUIFLAG_SCROLL_NO;*/
pInfo->pchHostCss = PszDupW(L"OE\\:APPLICATION { behavior:url(#DEFAULT#APPLICATION) }");
pInfo->pchHostNS = PszDupW(L"OE");
return S_OK;
}