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

  1. /*
  2. * f r n t b o d y . c p p
  3. *
  4. * Purpose:
  5. * Implementation of CFrontBody object. Derives from CBody to host the trident
  6. * control.
  7. *
  8. * History
  9. * April '97: erican - created
  10. *
  11. * Copyright (C) Microsoft Corp. 1995, 1996, 1997.
  12. */
  13. #include <pch.hxx>
  14. #include <wininet.h>
  15. #include <resource.h>
  16. #include "strconst.h"
  17. #include "xpcomm.h"
  18. #include "browser.h"
  19. #include "frntbody.h"
  20. #include <wininet.h>
  21. #include <mshtml.h>
  22. #include <goptions.h>
  23. #include <thormsgs.h>
  24. #include <spoolapi.h>
  25. #include <notify.h>
  26. #include <shlwapi.h>
  27. #include <shlwapip.h>
  28. #include "url.h"
  29. #include "bodyutil.h"
  30. #include "mimeutil.h"
  31. #include "instance.h"
  32. #include "storutil.h"
  33. #include "demand.h"
  34. #include "menures.h"
  35. #include "multiusr.h"
  36. #include "htmlhelp.h"
  37. #include "shared.h"
  38. #include "oetag.h"
  39. #include "subscr.h"
  40. #define IsBrowserMode() ( g_dwBrowserFlags & 0x07 )
  41. CFrontBody::CFrontBody(FOLDERTYPE ftType, IAthenaBrowser *pBrowser) : CMimeEditDocHost( /*MEBF_NOSCROLL*/ 0) //$27661: turn off noscroll
  42. {
  43. if (pBrowser)
  44. {
  45. m_pBrowser = pBrowser;
  46. m_pBrowser->AddRef();
  47. }
  48. m_phlbc = NULL;
  49. m_hwndOwner = NULL;
  50. m_pTag = 0;
  51. m_fOEFrontPage = TRUE;
  52. }
  53. CFrontBody::~CFrontBody()
  54. {
  55. if (m_pTag)
  56. {
  57. m_pTag->OnFrontPageClose();
  58. m_pTag->Release();
  59. m_pTag = NULL;
  60. }
  61. SafeRelease(m_pBrowser);
  62. SafeRelease(m_phlbc);
  63. }
  64. ////////////////////////////////////////////////////////////////////////
  65. //
  66. // IUnknown
  67. //
  68. ////////////////////////////////////////////////////////////////////////
  69. HRESULT CFrontBody::QueryInterface(REFIID riid, LPVOID FAR *lplpObj)
  70. {
  71. if (!lplpObj)
  72. return E_INVALIDARG;
  73. *lplpObj = NULL;
  74. if (IsEqualIID(riid, IID_IHlinkFrame))
  75. {
  76. *lplpObj = (IHlinkFrame *)this;
  77. AddRef();
  78. return NOERROR;
  79. }
  80. if (IsEqualIID(riid, IID_IServiceProvider))
  81. {
  82. *lplpObj = (IServiceProvider *)this;
  83. AddRef();
  84. return NOERROR;
  85. }
  86. if (IsEqualIID(riid, IID_IElementBehaviorFactory))
  87. {
  88. *lplpObj = (IElementBehaviorFactory *)this;
  89. AddRef();
  90. return NOERROR;
  91. }
  92. return CMimeEditDocHost::QueryInterface(riid, lplpObj);
  93. }
  94. ULONG CFrontBody::AddRef()
  95. {
  96. return CMimeEditDocHost::AddRef();
  97. }
  98. ULONG CFrontBody::Release()
  99. {
  100. return CMimeEditDocHost::Release();
  101. }
  102. ////////////////////////////////////////////////////////////////////////
  103. //
  104. // IHlinkFrame
  105. //
  106. ////////////////////////////////////////////////////////////////////////
  107. HRESULT CFrontBody::SetBrowseContext(LPHLINKBROWSECONTEXT phlbc)
  108. {
  109. ReplaceInterface(m_phlbc, phlbc);
  110. return NOERROR;
  111. }
  112. HRESULT CFrontBody::GetBrowseContext(LPHLINKBROWSECONTEXT *pphlbc)
  113. {
  114. if (pphlbc == NULL)
  115. return E_INVALIDARG;
  116. *pphlbc = m_phlbc;
  117. if (m_phlbc)
  118. m_phlbc->AddRef();
  119. return NOERROR;
  120. }
  121. static const struct {
  122. LPCWSTR pwszCmd;
  123. UINT uCmd;
  124. } s_rgCmdLookup[] =
  125. {
  126. { L"readMail", ID_GO_INBOX },
  127. { L"newMessage", ID_NEW_MSG_DEFAULT },
  128. { L"readNews", ID_GO_NEWS },
  129. { L"subscribeNews", ID_NEWSGROUPS },
  130. { L"addrBook", ID_ADDRESS_BOOK },
  131. { L"findAddr", ID_FIND_PEOPLE },
  132. { L"newNewsAccount", ID_CREATE_NEWS_ACCOUNT },
  133. { L"newMailAccount", ID_CREATE_MAIL_ACCOUNT },
  134. { L"help", ID_HELP_CONTENTS},
  135. { L"newNewsMessage", ID_NEW_NEWS_MESSAGE},
  136. { L"newUser", ID_NEW_IDENTITY},
  137. { L"switchUser", ID_SWITCH_IDENTITY},
  138. { L"noop", ID_NOOP},
  139. { L"findMessage", ID_FIND_MESSAGE},
  140. { L"logoff", ID_LOGOFF_IDENTITY},
  141. { L"manageUser", ID_MANAGE_IDENTITIES},
  142. };
  143. HRESULT CFrontBody::Navigate(DWORD grfHLNF, LPBC pbc, LPBINDSTATUSCALLBACK pbsc, LPHLINK phlNavigate)
  144. {
  145. HRESULT hr;
  146. LPWSTR pwszURL = NULL,
  147. pwszCmd = NULL;
  148. HINSTANCE hInst;
  149. WCHAR wsz[CCHMAX_STRINGRES],
  150. wszErr[CCHMAX_STRINGRES+INTERNET_MAX_URL_LENGTH+1];
  151. CStringParser sp;
  152. IF_FAILEXIT(hr = phlNavigate->GetStringReference(HLINKGETREF_ABSOLUTE, &pwszURL, NULL));
  153. if (pwszURL)
  154. {
  155. if (!StrCmpNIW(pwszURL, L"oecmd:", 6))
  156. {
  157. pwszCmd = pwszURL + 6;
  158. for (int i = 0; i < ARRAYSIZE(s_rgCmdLookup); i++)
  159. {
  160. if (!StrCmpNIW(pwszCmd, s_rgCmdLookup[i].pwszCmd, lstrlenW(s_rgCmdLookup[i].pwszCmd)))
  161. {
  162. switch (s_rgCmdLookup[i].uCmd)
  163. {
  164. case ID_HELP_CONTENTS:
  165. {
  166. LPSTR pszCmd = NULL;
  167. pwszCmd += ARRAYSIZE(s_rgCmdLookup[i].pwszCmd);
  168. IF_NULLEXIT(pszCmd = PszToANSI(CP_ACP, pwszCmd));
  169. sp.Init(pszCmd, lstrlen(pszCmd), 0);
  170. sp.ChParse("(");
  171. sp.ChParse(")");
  172. OEHtmlHelp(GetTopMostParent(m_hwnd), c_szCtxHelpFileHTML, HH_DISPLAY_TOPIC, (DWORD_PTR) (sp.CchValue() ? sp.PszValue() : NULL));
  173. MemFree(pszCmd);
  174. break;
  175. }
  176. case ID_CREATE_MAIL_ACCOUNT:
  177. case ID_CREATE_NEWS_ACCOUNT:
  178. _CreateNewAccount(s_rgCmdLookup[i].uCmd == ID_CREATE_MAIL_ACCOUNT);
  179. // handle account creation internally
  180. break;
  181. default:
  182. PostMessage(m_hwndOwner, WM_COMMAND, s_rgCmdLookup[i].uCmd, 0L);
  183. }
  184. SetStatusText(NULL);
  185. hr = S_OK;
  186. goto exit;
  187. }
  188. }
  189. AssertSz(0, "Navigation request to unknown oecmd link");
  190. hr = E_FAIL;
  191. }
  192. else
  193. {
  194. LPSTR pszURL = NULL;
  195. TCHAR sz[CCHMAX_STRINGRES],
  196. szErr[CCHMAX_STRINGRES+INTERNET_MAX_URL_LENGTH+1];
  197. IF_NULLEXIT(pszURL = PszToANSI(CP_ACP, pwszURL));
  198. hInst = ShellExecute(m_hwndOwner, NULL, pszURL, NULL, NULL, SW_SHOW);
  199. if (hInst <= (HINSTANCE)HINSTANCE_ERROR)
  200. {
  201. LoadString(g_hLocRes, idsErrURLExec, sz, ARRAYSIZE(sz));
  202. wnsprintf(szErr, ARRAYSIZE(szErr), sz, pszURL);
  203. // load title into wsz. We don't use AthMsgBox as our string maybe too long. AthMsgBox
  204. // will truncate at CCHMAX_STRINGRES.
  205. LoadString(g_hLocRes, idsAthena, sz, ARRAYSIZE(sz));
  206. MessageBox(m_hwndOwner, szErr, sz, MB_OK);
  207. }
  208. MemFree(pszURL);
  209. }
  210. }
  211. exit:
  212. if (pwszURL)
  213. CoTaskMemFree(pwszURL);
  214. return hr;
  215. }
  216. HRESULT CFrontBody::OnNavigate(DWORD grfHLNF, LPMONIKER pmkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
  217. {
  218. return E_NOTIMPL;
  219. }
  220. HRESULT CFrontBody::UpdateHlink(ULONG uHLID, LPMONIKER pmkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
  221. {
  222. return E_NOTIMPL;
  223. }
  224. ////////////////////////////////////////////////////////////////////////
  225. //
  226. // IServiceProvider
  227. //
  228. ////////////////////////////////////////////////////////////////////////
  229. HRESULT CFrontBody::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
  230. {
  231. if (IsEqualGUID(guidService, IID_IHlinkFrame))
  232. return QueryInterface(riid, ppvObject);
  233. if (IsEqualGUID(guidService, IID_IHlinkFrame))
  234. return QueryInterface(riid, ppvObject);
  235. if (IsEqualGUID(guidService, SID_SElementBehaviorFactory))
  236. return QueryInterface(riid, ppvObject);
  237. return E_NOINTERFACE;
  238. }
  239. ////////////////////////////////////////////////////////////////////////
  240. //
  241. // CDocHost
  242. //
  243. ////////////////////////////////////////////////////////////////////////
  244. void CFrontBody::OnDocumentReady()
  245. {
  246. URLSUB rgUrlSub[] = {
  247. { "msnlink", idsHelpMSWebHome }
  248. };
  249. // turn on link-tabbing for the front-page
  250. if (m_pCmdTarget)
  251. {
  252. VARIANTARG va;
  253. va.vt = VT_BOOL;
  254. va.boolVal = VARIANT_TRUE;
  255. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_TABLINKS, 0, &va, NULL);
  256. }
  257. // #42164
  258. // we defer-show the OE-front page via script. If an IEAK person overrides this
  259. // with a custom front-page, then we show as soon as we go document ready
  260. if (!m_fOEFrontPage)
  261. HrShow(TRUE);
  262. else
  263. {
  264. // if is is the std. OE page, then replace URL's
  265. SubstituteURLs(m_pDoc, rgUrlSub, ARRAYSIZE(rgUrlSub));
  266. }
  267. }
  268. ////////////////////////////////////////////////////////////////////////
  269. //
  270. // PUBLIC
  271. //
  272. ////////////////////////////////////////////////////////////////////////
  273. HRESULT CFrontBody::HrInit(HWND hwnd)
  274. {
  275. m_hwndOwner = hwnd;
  276. return CMimeEditDocHost::HrInit(hwnd, IBOF_TABLINKS, NULL);
  277. }
  278. HRESULT CFrontBody::HrLoadPage()
  279. {
  280. HRESULT hr = S_OK;
  281. // bobn: brianv says we have to take this out...
  282. /*if (IsBrowserMode())
  283. {
  284. hr = HrLoadURL("res://msoeres.dll/example.eml");
  285. m_fOEFrontPage = FALSE;
  286. g_dwBrowserFlags = 0;
  287. }
  288. else*/
  289. {
  290. DWORD cbData;
  291. TCHAR szURL[INTERNET_MAX_URL_LENGTH + 1];
  292. TCHAR *pszUrl;
  293. LPSTR pszUrlFree=NULL;
  294. *szURL = 0;
  295. cbData = sizeof(szURL);
  296. AthUserGetValue(NULL, c_szFrontPagePath, NULL, (LPBYTE)szURL, &cbData);
  297. if (*szURL)
  298. {
  299. pszUrl = szURL;
  300. m_fOEFrontPage = FALSE;
  301. }
  302. else
  303. {
  304. pszUrlFree = PszAllocResUrl(g_dwAthenaMode & MODE_NEWSONLY ? "frntnews.htm" : "frntpage.htm");
  305. pszUrl = pszUrlFree;
  306. }
  307. hr = HrLoadURL(pszUrl);
  308. SafeMemFree(pszUrlFree);
  309. }
  310. return hr;
  311. }
  312. HRESULT CFrontBody::SetStatusText(LPCOLESTR pszW)
  313. {
  314. WCHAR wszRes[CCHMAX_STRINGRES];
  315. LPWSTR pszStatusW=0;
  316. HRESULT hr;
  317. if (pszW && !StrCmpNIW(pszW, L"oecmd:", 6))
  318. {
  319. for (int i = 0; i < ARRAYSIZE(s_rgCmdLookup); i++)
  320. {
  321. if (!StrCmpNIW(pszW+6, s_rgCmdLookup[i].pwszCmd, lstrlenW(s_rgCmdLookup[i].pwszCmd)))
  322. {
  323. *wszRes = 0;
  324. LoadStringWrapW(g_hLocRes, MH(s_rgCmdLookup[i].uCmd), wszRes, ARRAYSIZE(wszRes));
  325. // If this fails, worse that happens is that the status text is nulled.
  326. pszStatusW = PszDupW(wszRes);
  327. pszW = pszStatusW;
  328. break;
  329. }
  330. }
  331. }
  332. hr = CMimeEditDocHost::SetStatusText(pszW);
  333. MemFree(pszStatusW);
  334. return hr;
  335. }
  336. HRESULT CFrontBody::_CreateNewAccount(BOOL fMail)
  337. {
  338. IImnAccount *pAcct=0,
  339. *pAcctDef;
  340. FOLDERID id;
  341. DWORD dwServer=0;
  342. CHAR rgch[CCHMAX_ACCOUNT_NAME];
  343. HRESULT hr;
  344. DWORD dwPropGet,
  345. dwPropSet;
  346. // create a new account object
  347. hr = g_pAcctMan->CreateAccountObject(fMail ? ACCT_MAIL : ACCT_NEWS, &pAcct);
  348. if (FAILED(hr))
  349. {
  350. TraceResult(hr);
  351. goto exit;
  352. }
  353. // If creating a new news account, try and use default-mail information. If creating a new mail account, try
  354. // and use default-news information (if any). We don't use def-mail for mail accounts as the front-page only shows
  355. // links for account-creation if there are 0 accounts of that type.
  356. if (g_pAcctMan->GetDefaultAccount(fMail ? ACCT_NEWS : ACCT_MAIL, &pAcctDef)==S_OK)
  357. {
  358. dwPropGet = fMail ? AP_NNTP_DISPLAY_NAME : AP_SMTP_DISPLAY_NAME;
  359. dwPropSet = fMail ? AP_SMTP_DISPLAY_NAME : AP_NNTP_DISPLAY_NAME;
  360. if (pAcctDef->GetPropSz(dwPropGet, rgch, ARRAYSIZE(rgch))==S_OK)
  361. pAcct->SetPropSz(dwPropSet, rgch);
  362. dwPropGet = fMail ? AP_NNTP_EMAIL_ADDRESS : AP_SMTP_EMAIL_ADDRESS;
  363. dwPropSet = fMail ? AP_SMTP_EMAIL_ADDRESS : AP_NNTP_EMAIL_ADDRESS;
  364. if (pAcctDef->GetPropSz(dwPropGet, rgch, ARRAYSIZE(rgch))==S_OK)
  365. pAcct->SetPropSz(dwPropSet, rgch);
  366. pAcctDef->Release();
  367. }
  368. // show the account wizard dialog and allow the user to setup properties
  369. hr = pAcct->DoWizard(m_hwndOwner, ACCT_WIZ_MIGRATE | ACCT_WIZ_INTERNETCONNECTION |
  370. ACCT_WIZ_HTTPMAIL | ACCT_WIZ_OE);
  371. if (FAILED(hr))
  372. {
  373. TraceResult(hr);
  374. goto exit;
  375. }
  376. // find out what servers were added
  377. hr = pAcct->GetServerTypes(&dwServer);
  378. if (FAILED(hr))
  379. {
  380. TraceResult(hr);
  381. goto exit;
  382. }
  383. // if we added a new news or IMAP account, ask the user if they want to see the subscription dialog
  384. if ( ((dwServer & SRV_IMAP) || (dwServer & SRV_NNTP)) &&
  385. IDYES == AthMessageBoxW(m_hwndOwner, MAKEINTRESOURCEW(idsAthena),
  386. dwServer & SRV_NNTP ? MAKEINTRESOURCEW(idsDisplayNewsSubDlg) : MAKEINTRESOURCEW(idsDisplayImapSubDlg),
  387. 0, MB_ICONEXCLAMATION | MB_YESNO))
  388. {
  389. // get the account-id
  390. hr = pAcct->GetPropSz(AP_ACCOUNT_ID, rgch, ARRAYSIZE(rgch));
  391. if (FAILED(hr))
  392. {
  393. TraceResult(hr);
  394. goto exit;
  395. }
  396. // find the associated node in the store
  397. hr = g_pStore->FindServerId(rgch, &id);
  398. if (FAILED(hr))
  399. {
  400. TraceResult(hr);
  401. goto exit;
  402. }
  403. //The user wants to download the list of newsgroups, so if we are offline, go online
  404. if (g_pConMan)
  405. g_pConMan->SetGlobalOffline(FALSE);
  406. // finally, show the subscription dialog
  407. DoSubscriptionDialog(m_hwndOwner, dwServer & SRV_NNTP, id);
  408. }
  409. exit:
  410. ReleaseObj(pAcct);
  411. return hr;
  412. }
  413. HRESULT CFrontBody::HrClose()
  414. {
  415. if (m_pTag)
  416. {
  417. m_pTag->OnFrontPageClose();
  418. m_pTag->Release();
  419. m_pTag = NULL;
  420. }
  421. SafeRelease(m_pBrowser);
  422. return CMimeEditDocHost::HrClose();
  423. }
  424. HRESULT CFrontBody::FindBehavior(LPOLESTR pchBehavior, LPOLESTR pchBehaviorUrl, IElementBehaviorSite* pSite, IElementBehavior** ppBehavior)
  425. {
  426. HRESULT hr;
  427. if ((StrCmpIW(pchBehavior, L"APPLICATION")==0 && StrCmpIW(pchBehaviorUrl, L"#DEFAULT#APPLICATION")==0))
  428. {
  429. if (!m_pTag)
  430. {
  431. m_pTag = new COETag(m_pBrowser, this);
  432. if (!m_pTag)
  433. return E_OUTOFMEMORY;
  434. }
  435. return m_pTag->QueryInterface(IID_IElementBehavior, (LPVOID *)ppBehavior);
  436. }
  437. return E_FAIL;
  438. }
  439. HRESULT CFrontBody::GetHostInfo( DOCHOSTUIINFO* pInfo )
  440. {
  441. pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
  442. pInfo->dwFlags = DOCHOSTUIFLAG_DIV_BLOCKDEFAULT|DOCHOSTUIFLAG_OPENNEWWIN|
  443. DOCHOSTUIFLAG_NO3DBORDER|DOCHOSTUIFLAG_CODEPAGELINKEDFONTS;
  444. //This sets the flags that match the browser's encoding
  445. fGetBrowserUrlEncoding(&pInfo->dwFlags);
  446. // bobn: brianv says we have to take this out...
  447. /*if (IsBrowserMode())
  448. pInfo->dwFlags |= DOCHOSTUIFLAG_SCROLL_NO;*/
  449. pInfo->pchHostCss = PszDupW(L"OE\\:APPLICATION { behavior:url(#DEFAULT#APPLICATION) }");
  450. pInfo->pchHostNS = PszDupW(L"OE");
  451. return S_OK;
  452. }