Source code of Windows XP (NT5)
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.

743 lines
22 KiB

  1. /*
  2. * contmenu.cpp - Context menu implementation for URL class.
  3. */
  4. /* Headers
  5. **********/
  6. #include "project.hpp"
  7. #pragma hdrstop
  8. #include <mapi.h>
  9. #include "resource.h"
  10. #ifdef UNIX
  11. #include <tchar.h>
  12. #include <inetreg.h>
  13. static HRESULT UnixReadNews(HWND hwndParent, PCSTR pszCmdLine);
  14. #endif
  15. /* Types
  16. ********/
  17. /* MAPISendMail() typedef */
  18. typedef ULONG (FAR PASCAL *MAPISENDMAILPROC)(LHANDLE lhSession, ULONG ulUIParam, lpMapiMessageA lpMessage, FLAGS flFlags, ULONG ulReserved);
  19. /* RunDLL32 DLL entry point typedef */
  20. typedef void (WINAPI *RUNDLL32PROC)(HWND hwndParent, HINSTANCE hinst, PSTR pszCmdLine, int nShowCmd);
  21. /* Module Constants
  22. *******************/
  23. #pragma data_seg(DATA_SEG_READ_ONLY)
  24. // case-insensitive
  25. PRIVATE_DATA const char s_cszFileProtocolPrefix[] = "file:";
  26. PRIVATE_DATA const char s_cszMailToProtocolPrefix[] = "mailto:";
  27. PRIVATE_DATA const char s_cszRLoginProtocolPrefix[] = "rlogin:";
  28. PRIVATE_DATA const char s_cszTelnetProtocolPrefix[] = "telnet:";
  29. PRIVATE_DATA const char s_cszTN3270ProtocolPrefix[] = "tn3270:";
  30. PRIVATE_DATA const char s_cszNewsDLL[] = "mcm.dll";
  31. #ifndef UNIX
  32. PRIVATE_DATA const char s_cszTelnetApp[] = "telnet.exe";
  33. #else
  34. PRIVATE_DATA const char s_cszTelnetApp[] = "telnet";
  35. #endif
  36. PRIVATE_DATA const char s_cszMAPISection[] = "Mail";
  37. PRIVATE_DATA const char s_cszMAPIKey[] = "CMCDLLName32";
  38. PRIVATE_DATA const char s_cszMAPISendMail[] = "MAPISendMail";
  39. PRIVATE_DATA const char s_cszNewsProtocolHandler[] = "NewsProtocolHandler";
  40. #pragma data_seg()
  41. /***************************** Exported Functions ****************************/
  42. #pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
  43. extern "C" void WINAPI OpenURL(HWND hwndParent, HINSTANCE hinst,
  44. PSTR pszCmdLine, int nShowCmd)
  45. {
  46. HRESULT hr;
  47. InternetShortcut intshcut;
  48. int nResult;
  49. DebugEntry(OpenURL);
  50. ASSERT(IS_VALID_HANDLE(hwndParent, WND));
  51. ASSERT(IS_VALID_HANDLE(hinst, INSTANCE));
  52. ASSERT(IS_VALID_STRING_PTR(pszCmdLine, STR));
  53. ASSERT(IsValidShowCmd(nShowCmd));
  54. // Assume the entire command line is an Internet Shortcut file path.
  55. TrimWhiteSpace(pszCmdLine);
  56. TRACE_OUT(("OpenURL(): Trying to open Internet Shortcut %s.",
  57. pszCmdLine));
  58. hr = intshcut.LoadFromFile(pszCmdLine, TRUE);
  59. if (hr == S_OK)
  60. {
  61. URLINVOKECOMMANDINFO urlici;
  62. urlici.dwcbSize = sizeof(urlici);
  63. urlici.hwndParent = hwndParent;
  64. urlici.pcszVerb = NULL;
  65. urlici.dwFlags = (IURL_INVOKECOMMAND_FL_ALLOW_UI |
  66. IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB);
  67. hr = intshcut.InvokeCommand(&urlici);
  68. }
  69. else
  70. {
  71. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  72. MAKEINTRESOURCE(IDS_LOADFROMFILE_FAILED),
  73. (MB_OK | MB_ICONEXCLAMATION), &nResult, pszCmdLine)) {
  74. ASSERT(nResult == IDOK);
  75. }
  76. }
  77. DebugExitVOID(OpenURL);
  78. return;
  79. }
  80. extern "C" void WINAPI FileProtocolHandler(HWND hwndParent, HINSTANCE hinst,
  81. PSTR pszCmdLine, int nShowCmd)
  82. {
  83. char szDefaultVerb[MAX_PATH_LEN];
  84. PCSTR pcszVerb;
  85. HINSTANCE hinstExec;
  86. int nResult;
  87. PARSEDURL pu;
  88. DebugEntry(FileProtocolHandler);
  89. ASSERT(IS_VALID_HANDLE(hwndParent, WND));
  90. ASSERT(IS_VALID_HANDLE(hinst, INSTANCE));
  91. ASSERT(IS_VALID_STRING_PTR(pszCmdLine, STR));
  92. ASSERT(IsValidShowCmd(nShowCmd));
  93. // Assume the entire command line is a file: URL.
  94. TrimWhiteSpace(pszCmdLine);
  95. pu.cbSize = sizeof(pu);
  96. if (S_OK == ParseURL(pszCmdLine, &pu) &&
  97. URL_SCHEME_FILE == pu.nScheme)
  98. {
  99. pszCmdLine = (LPSTR)pu.pszSuffix;
  100. }
  101. // Get default verb if available.
  102. if (GetPathDefaultVerb(pszCmdLine, szDefaultVerb, sizeof(szDefaultVerb)))
  103. pcszVerb = szDefaultVerb;
  104. else
  105. pcszVerb = NULL;
  106. TRACE_OUT(("FileProtocolHandler(): Invoking %s verb on %s.",
  107. pcszVerb ? pcszVerb : "open",
  108. pszCmdLine));
  109. hinstExec = ShellExecute(hwndParent, pcszVerb, pszCmdLine, NULL, NULL,
  110. nShowCmd);
  111. if (hinstExec > (HINSTANCE)32)
  112. TRACE_OUT(("FileProtocolHandler(): ShellExecute() %s verb on %s succeeded.",
  113. pcszVerb ? pcszVerb : "open",
  114. pszCmdLine));
  115. else
  116. {
  117. WARNING_OUT(("FileProtocolHandler(): ShellExecute() %s verb on %s failed, returning %lu.",
  118. pcszVerb ? pcszVerb : "open",
  119. pszCmdLine,
  120. hinstExec));
  121. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  122. MAKEINTRESOURCE(IDS_SHELLEXECUTE_FAILED),
  123. (MB_OK | MB_ICONEXCLAMATION), &nResult, pszCmdLine)) {
  124. ASSERT(nResult == IDOK);
  125. }
  126. }
  127. DebugExitVOID(FileProtocolHandler);
  128. return;
  129. }
  130. extern "C" void WINAPI MailToProtocolHandler(HWND hwndParent, HINSTANCE hinst,
  131. PSTR pszCmdLine, int nShowCmd)
  132. {
  133. int nResult;
  134. char szMAPIDLL[MAX_PATH_LEN];
  135. DebugEntry(MailToProtocolHandler);
  136. ASSERT(IS_VALID_HANDLE(hwndParent, WND));
  137. ASSERT(IS_VALID_HANDLE(hinst, INSTANCE));
  138. ASSERT(IS_VALID_STRING_PTR(pszCmdLine, STR));
  139. ASSERT(IsValidShowCmd(nShowCmd));
  140. if (GetProfileString(s_cszMAPISection, s_cszMAPIKey, EMPTY_STRING,
  141. szMAPIDLL, sizeof(szMAPIDLL)) > 0)
  142. {
  143. HINSTANCE hinstMAPI;
  144. TRACE_OUT(("MailToProtocolHandler(): MAPI provider DLL is %s.",
  145. szMAPIDLL));
  146. hinstMAPI = LoadLibrary(szMAPIDLL);
  147. if (hinstMAPI)
  148. {
  149. MAPISENDMAILPROC MAPISendMailProc;
  150. MAPISendMailProc = (MAPISENDMAILPROC)GetProcAddress(
  151. hinstMAPI,
  152. s_cszMAPISendMail);
  153. if (MAPISendMailProc)
  154. {
  155. MapiRecipDescA mapito;
  156. MapiMessage mapimsg;
  157. ULONG ulResult;
  158. // Assume the entire command line is a mailto: URL.
  159. TrimWhiteSpace(pszCmdLine);
  160. // Skip over any url: prefix.
  161. if (! lstrnicmp(pszCmdLine, g_cszURLPrefix, g_ucbURLPrefixLen))
  162. pszCmdLine += g_ucbURLPrefixLen;
  163. // Skip over any mailto: prefix.
  164. // (- 1) for null terminator.
  165. if (! lstrnicmp(pszCmdLine, s_cszMailToProtocolPrefix,
  166. SIZECHARS(s_cszMailToProtocolPrefix) - 1))
  167. pszCmdLine += SIZECHARS(s_cszMailToProtocolPrefix) - 1;
  168. ZeroMemory(&mapito, sizeof(mapito));
  169. mapito.ulRecipClass = MAPI_TO;
  170. mapito.lpszName = pszCmdLine;
  171. ZeroMemory(&mapimsg, sizeof(mapimsg));
  172. mapimsg.nRecipCount = 1;
  173. mapimsg.lpRecips = &mapito;
  174. TRACE_OUT(("MailToProtocolHandler(): Trying to send mail to %s.",
  175. mapito.lpszName));
  176. ulResult = (*MAPISendMailProc)(NULL, 0, &mapimsg,
  177. (MAPI_LOGON_UI | MAPI_DIALOG), 0);
  178. if (ulResult == SUCCESS_SUCCESS)
  179. TRACE_OUT(("MailToProtocolHandler(): MAPISendMail() to %s succeeded.",
  180. pszCmdLine));
  181. else
  182. {
  183. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  184. MAKEINTRESOURCE(IDS_MAPI_MAPISENDMAIL_FAILED),
  185. (MB_OK | MB_ICONEXCLAMATION), &nResult)) {
  186. ASSERT(nResult == IDOK);
  187. }
  188. }
  189. }
  190. else
  191. {
  192. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  193. MAKEINTRESOURCE(IDS_MAPI_GETPROCADDRESS_FAILED),
  194. (MB_OK | MB_ICONEXCLAMATION), &nResult,
  195. szMAPIDLL, s_cszMAPISendMail)) {
  196. ASSERT(nResult == IDOK);
  197. }
  198. }
  199. EVAL(FreeLibrary(hinstMAPI));
  200. }
  201. else
  202. {
  203. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  204. MAKEINTRESOURCE(IDS_MAPI_LOADLIBRARY_FAILED),
  205. (MB_OK | MB_ICONEXCLAMATION), &nResult, szMAPIDLL)) {
  206. ASSERT(nResult == IDOK);
  207. }
  208. }
  209. }
  210. else
  211. {
  212. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  213. MAKEINTRESOURCE(IDS_NO_MAPI_PROVIDER),
  214. (MB_OK | MB_ICONEXCLAMATION), &nResult)) {
  215. ASSERT(nResult == IDOK);
  216. }
  217. }
  218. DebugExitVOID(MailToProtocolHandler);
  219. return;
  220. }
  221. extern "C" void WINAPI NewsProtocolHandler(HWND hwndParent, HINSTANCE hinst,
  222. PSTR pszCmdLine, int nShowCmd)
  223. {
  224. int nResult;
  225. HINSTANCE hinstNews;
  226. DebugEntry(NewsProtocolHandler);
  227. ASSERT(IS_VALID_HANDLE(hwndParent, WND));
  228. ASSERT(IS_VALID_HANDLE(hinst, INSTANCE));
  229. ASSERT(IS_VALID_STRING_PTR(pszCmdLine, STR));
  230. ASSERT(IsValidShowCmd(nShowCmd));
  231. #ifndef UNIX
  232. // Assume the entire command line is a news: URL.
  233. TrimWhiteSpace(pszCmdLine);
  234. // Skip over any url: prefix.
  235. if (! lstrnicmp(pszCmdLine, g_cszURLPrefix, g_ucbURLPrefixLen))
  236. pszCmdLine += g_ucbURLPrefixLen;
  237. hinstNews = LoadLibrary(s_cszNewsDLL);
  238. if (hinstNews)
  239. {
  240. RUNDLL32PROC RealNewsProtocolHandler;
  241. RealNewsProtocolHandler = (RUNDLL32PROC)GetProcAddress(hinstNews,
  242. s_cszNewsProtocolHandler);
  243. if (RealNewsProtocolHandler)
  244. {
  245. TRACE_OUT(("NewsProtocolHandler(): Trying to open %s.",
  246. pszCmdLine));
  247. (*RealNewsProtocolHandler)(hwndParent, hinst, pszCmdLine, nShowCmd);
  248. TRACE_OUT(("NewsProtocolHandler(): Returned from NewsProtocolHandler()."));
  249. }
  250. else
  251. {
  252. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  253. MAKEINTRESOURCE(IDS_NEWS_GETPROCADDRESS_FAILED),
  254. (MB_OK | MB_ICONEXCLAMATION), &nResult)) {
  255. ASSERT(nResult == IDOK);
  256. }
  257. }
  258. EVAL(FreeLibrary(hinstNews));
  259. }
  260. else
  261. {
  262. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  263. MAKEINTRESOURCE(IDS_NEWS_LOADLIBRARY_FAILED),
  264. (MB_OK | MB_ICONEXCLAMATION), &nResult)) {
  265. ASSERT(nResult == IDOK);
  266. }
  267. }
  268. #else
  269. UnixReadNews(hwndParent, pszCmdLine);
  270. #endif
  271. DebugExitVOID(NewsProtocolHandler);
  272. return;
  273. }
  274. #ifndef ISSPACE
  275. #define ISSPACE(ch) (((ch) == 32) || ((unsigned)((ch) - 9)) <= 13 - 9)
  276. #endif
  277. #ifndef ISQUOTE
  278. #define ISQUOTE(ch) ((ch) == '\"' || (ch) == '\'')
  279. #endif
  280. extern "C" void WINAPI TelnetProtocolHandler(HWND hwndParent, HINSTANCE hinst,
  281. PSTR pszCmdLine, int nShowCmd)
  282. {
  283. HRESULT hr;
  284. int nResult;
  285. char *p;
  286. char *pDest;
  287. BOOL fRemove;
  288. #ifdef UNIX
  289. char szApp[MAX_PATH];
  290. char szArgs[MAX_PATH];
  291. #ifndef ANSI_SHELL32_ON_UNIX
  292. char szCmdLine[MAX_PATH];
  293. memset(szCmdLine, 0, MAX_PATH);
  294. SHUnicodeToAnsi((LPWSTR)pszCmdLine, szCmdLine, MAX_PATH);
  295. pszCmdLine = szCmdLine;
  296. #endif /* ANSI_SHELL32_ON_UNIX */
  297. #endif
  298. DebugEntry(TelnetProtocolHandler);
  299. ASSERT(IS_VALID_HANDLE(hwndParent, WND));
  300. ASSERT(IS_VALID_HANDLE(hinst, INSTANCE));
  301. ASSERT(IS_VALID_STRING_PTR(pszCmdLine, STR));
  302. ASSERT(IsValidShowCmd(nShowCmd));
  303. // Assume the entire command line is a telnet URL.
  304. TrimWhiteSpace(pszCmdLine);
  305. // Skip over any url: prefix.
  306. if (! lstrnicmp(pszCmdLine, g_cszURLPrefix, g_ucbURLPrefixLen))
  307. pszCmdLine += g_ucbURLPrefixLen;
  308. // Skip over any telnet:, rlogin:, or tn3270: prefix.
  309. // (- 1) for null terminator.
  310. if (! lstrnicmp(pszCmdLine, s_cszTelnetProtocolPrefix,
  311. SIZECHARS(s_cszTelnetProtocolPrefix) - 1))
  312. pszCmdLine += SIZECHARS(s_cszTelnetProtocolPrefix) - 1;
  313. else if (! lstrnicmp(pszCmdLine, s_cszRLoginProtocolPrefix,
  314. SIZECHARS(s_cszRLoginProtocolPrefix) - 1))
  315. pszCmdLine += SIZECHARS(s_cszRLoginProtocolPrefix) - 1;
  316. else if (! lstrnicmp(pszCmdLine, s_cszTN3270ProtocolPrefix,
  317. SIZECHARS(s_cszTN3270ProtocolPrefix) - 1))
  318. pszCmdLine += SIZECHARS(s_cszTN3270ProtocolPrefix) - 1;
  319. // Remove leading and trailing slashes.
  320. TrimSlashes(pszCmdLine);
  321. // Skip user name if given
  322. p = StrChr(pszCmdLine, '@');
  323. if (p)
  324. pszCmdLine = p + 1;
  325. // Eliminate double quotes...should be no need for these
  326. // unless trouble is afoot.
  327. for (pDest = p = pszCmdLine; *p; p++)
  328. {
  329. if (!ISQUOTE(*p))
  330. {
  331. *pDest = *p;
  332. pDest++;
  333. }
  334. }
  335. *pDest = '\0';
  336. // For security reasons, strip the filename cmdline option
  337. if (pszCmdLine)
  338. {
  339. for (p = pszCmdLine; *p; p++)
  340. {
  341. // Be careful and don't nuke servernames that start with -f.
  342. // Since hostnames can't start with a dash, ensure previous char is
  343. // whitespace, or we're at the beginning.
  344. //
  345. // Also, -a sends credentials over the wire, so strip it, too.
  346. if ((*p == '/' || *p == '-') &&
  347. (*(p+1) == 'f' || *(p+1) == 'F' || *(p+1) == 'a' || *(p+1) == 'A'))
  348. {
  349. fRemove = TRUE;
  350. if (!((p == pszCmdLine || ISSPACE(*(p-1)) || ISQUOTE(*(p-1)) )))
  351. {
  352. char *pPortChar = p-1;
  353. // Doesn't meet easy criteria, but it might be harder to
  354. // detect, such as site:-ffilename. In this case, consider
  355. // the -f piece unsafe if everything between -f and a colon
  356. // to the left is a digit (no digits will also be unsafe).
  357. // If anything else is hit first, then consider it to
  358. // be part of the hostname. Walking to the beginning
  359. // be considered safe (e.g. "80-ffilename" would be considered
  360. // the hostname).
  361. while (pPortChar >= pszCmdLine && *pPortChar != ':')
  362. {
  363. if (*pPortChar < '0' || *pPortChar > '9')
  364. {
  365. fRemove = FALSE;
  366. break;
  367. }
  368. pPortChar--;
  369. }
  370. if (pPortChar < pszCmdLine)
  371. fRemove = FALSE;
  372. }
  373. if (!fRemove)
  374. continue;
  375. BOOL fQuotedFilename = FALSE;
  376. LPSTR pStart = p;
  377. // move past -f
  378. p+=2;
  379. // Skip over whitespace and filename following -f option
  380. if (*(p-1) == 'f' || *(p-1) == 'F')
  381. {
  382. while (*p && ISSPACE(*p))
  383. p++;
  384. // but wait, it may be a long filename surrounded by quotes
  385. if (ISQUOTE(*p))
  386. {
  387. fQuotedFilename = TRUE;
  388. p++;
  389. }
  390. // Loop until null OR whitespace if not quoted pathname OR quote if a quoted pathname
  391. while (!((*p == '\0') ||
  392. (ISSPACE(*p) && !fQuotedFilename) ||
  393. (ISQUOTE(*p) && fQuotedFilename)))
  394. p++;
  395. }
  396. // phase out the -a and -f options, but keep going to search the rest of the string
  397. memmove((VOID *)pStart, (VOID *)p, strlen(p)+1);
  398. p = pStart-1;
  399. }
  400. }
  401. }
  402. // If a port has been specified, turn ':' into space, which will make the
  403. // port become the second command line argument.
  404. p = StrChr(pszCmdLine, ':');
  405. if (p)
  406. *p = ' ';
  407. TRACE_OUT(("TelnetProtocolHandler(): Trying telnet to %s.",
  408. pszCmdLine));
  409. #ifndef UNIX
  410. hr = MyExecute(s_cszTelnetApp, pszCmdLine, 0);
  411. #else
  412. // On UNIX, telnet is not GUI application, so we need to create
  413. // separate xterm for it if we want to seet in in the separate window.
  414. strcpy(szApp, "xterm");
  415. wnsprintf(szArgs, sizeof(szArgs), "-e %s %s", s_cszTelnetApp, pszCmdLine);
  416. hr = MyExecute(szApp, szArgs, 0);
  417. #endif
  418. switch (hr)
  419. {
  420. case S_OK:
  421. break;
  422. case E_FILE_NOT_FOUND:
  423. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  424. MAKEINTRESOURCE(IDS_TELNET_APP_NOT_FOUND),
  425. (MB_OK | MB_ICONEXCLAMATION), &nResult,
  426. s_cszTelnetApp)) {
  427. ASSERT(nResult == IDOK);
  428. }
  429. break;
  430. case E_OUTOFMEMORY:
  431. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  432. MAKEINTRESOURCE(IDS_OPEN_INTSHCUT_OUT_OF_MEMORY),
  433. (MB_OK | MB_ICONEXCLAMATION), &nResult)) {
  434. ASSERT(nResult == IDOK);
  435. }
  436. break;
  437. default:
  438. ASSERT(hr == E_FAIL);
  439. if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
  440. MAKEINTRESOURCE(IDS_TELNET_EXEC_FAILED),
  441. (MB_OK | MB_ICONEXCLAMATION), &nResult,
  442. s_cszTelnetApp)) {
  443. ASSERT(nResult == IDOK);
  444. }
  445. break;
  446. }
  447. DebugExitVOID(TelnetProtocolHandler);
  448. return;
  449. }
  450. #ifdef UNIX
  451. #define OE_NEWS_COMMAND_KEY TEXT("Software\\Clients\\News\\Outlook Express\\shell\\open\\command")
  452. #define OE_URL_COMMAND_NAME TEXT("URLCommand")
  453. #define IE_HOME_ENVIRONMENT TEXT("MWDEV")
  454. HRESULT UnixLaunchOENews(PCSTR pszCmdLine)
  455. {
  456. HRESULT hr = S_OK;
  457. TCHAR *tszCommand = NULL;
  458. TCHAR tszIEHome[MAX_PATH];
  459. DWORD cchIEHome;
  460. DWORD cchCommand;
  461. DWORD dwDisposition;
  462. TCHAR *pchPos;
  463. BOOL bMailed;
  464. STARTUPINFO stInfo;
  465. HKEY hkey = NULL;
  466. int i;
  467. #ifndef ANSI_SHELL32_ON_UNIX
  468. char szCmdLine[MAX_PATH];
  469. memset(szCmdLine, 0, MAX_PATH);
  470. SHUnicodeToAnsi((LPWSTR)pszCmdLine, szCmdLine, MAX_PATH);
  471. pszCmdLine = szCmdLine;
  472. #endif /* ANSI_SHELL32_ON_UNIX */
  473. cchIEHome = GetEnvironmentVariable(IE_HOME_ENVIRONMENT, tszIEHome, MAX_PATH);
  474. if (cchIEHome)
  475. {
  476. _tcscat(tszIEHome, TEXT("/bin"));
  477. }
  478. else
  479. {
  480. return E_FAIL;
  481. }
  482. hr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, OE_NEWS_COMMAND_KEY, 0, NULL, 0, KEY_READ, NULL, &hkey, &dwDisposition);
  483. if (hr != ERROR_SUCCESS)
  484. {
  485. goto Cleanup;
  486. }
  487. hr = RegQueryValueEx(hkey, OE_URL_COMMAND_NAME, NULL, NULL, (LPBYTE)NULL, &cchCommand);
  488. if (hr != ERROR_SUCCESS)
  489. {
  490. goto Cleanup;
  491. }
  492. cchCommand += _tcslen(tszIEHome) + _tcslen(pszCmdLine) + 1;
  493. tszCommand = (TCHAR*)malloc((cchCommand)*sizeof(TCHAR));
  494. _tcscpy(tszCommand, tszIEHome);
  495. _tcscat(tszCommand, TEXT("/"));
  496. dwDisposition = _tcslen(tszCommand);
  497. hr = RegQueryValueEx(hkey, OE_URL_COMMAND_NAME, NULL, NULL, (LPBYTE)(&tszCommand[dwDisposition]), &cchCommand);
  498. if (hr != ERROR_SUCCESS)
  499. {
  500. goto Cleanup;
  501. }
  502. _tcscat(tszCommand, pszCmdLine);
  503. memset(&stInfo, 0, sizeof(stInfo));
  504. stInfo.cb = sizeof(stInfo);
  505. bMailed = CreateProcess(NULL, tszCommand, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &stInfo, NULL);
  506. Cleanup:
  507. if ( hkey != NULL )
  508. RegCloseKey(hkey);
  509. if (tszCommand)
  510. free(tszCommand);
  511. return hr;
  512. }
  513. HRESULT UnixReadNews(HWND hWndParent, PCSTR pszCmdLine)
  514. {
  515. HRESULT hr = S_FALSE;
  516. CHAR szCommand[MAX_PATH];
  517. CHAR szExpandedCommand[MAX_PATH];
  518. UINT nCommandSize;
  519. int i;
  520. HKEY hkey;
  521. DWORD dw;
  522. BOOL bMailed;
  523. STARTUPINFOA stInfo;
  524. DWORD dwType;
  525. DWORD dwSize = sizeof(DWORD);
  526. DWORD dwUseOENews;
  527. hr = SHGetValue(IE_USE_OE_NEWS_HKEY, IE_USE_OE_NEWS_KEY, IE_USE_OE_NEWS_VALUE,
  528. &dwType, (void*)&dwUseOENews, &dwSize);
  529. if ((hr) && (dwType != REG_DWORD))
  530. {
  531. // The default value for mail is FALSE
  532. dwUseOENews = FALSE;
  533. }
  534. if (dwUseOENews)
  535. {
  536. return UnixLaunchOENews(pszCmdLine);
  537. }
  538. hr = RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_NEWSCLIENTS, 0, NULL, 0, KEY_READ, NULL, &hkey, &dw);
  539. if (hr != ERROR_SUCCESS)
  540. goto Cleanup;
  541. dw = MAX_PATH;
  542. hr = RegQueryValueEx(hkey, REGSTR_PATH_CURRENT, NULL, NULL, (LPBYTE)szCommand, &dw);
  543. if (hr != ERROR_SUCCESS)
  544. {
  545. RegCloseKey(hkey);
  546. goto Cleanup;
  547. }
  548. if (strlen(szCommand) == 0)
  549. {
  550. MessageBox(hWndParent,
  551. TEXT("There is currently no default association for \"news:\" links in UNIX Internet Explorer. If you have a favorite news reader that supports news specifications on the command line (id and group name), you can define an association for \"news:\" links for this program in the View->Internet Options, Programs Tab.\n"),
  552. TEXT("Microsoft Internet Explorer"),
  553. MB_OK|MB_ICONSTOP);
  554. return S_FALSE;
  555. }
  556. dw = ExpandEnvironmentStringsA(szCommand, szExpandedCommand, MAX_PATH);
  557. if (!dw)
  558. {
  559. strcpy(szExpandedCommand, szCommand);
  560. }
  561. strcpy(szCommand, szExpandedCommand);
  562. for (i = lstrlen(szCommand)-1; i >= 0; i--)
  563. if (szCommand[i] == '/')
  564. {
  565. szCommand[i] = '\0';
  566. break;
  567. }
  568. strcat(szCommand, " ");
  569. strcat(szCommand, (pszCmdLine + strlen("news:")));
  570. memset(&stInfo, 0, sizeof(stInfo));
  571. stInfo.cb = sizeof(stInfo);
  572. bMailed = CreateProcessA(szExpandedCommand, szCommand, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &stInfo, NULL);
  573. Cleanup:
  574. return S_OK;
  575. }
  576. #endif
  577. #pragma warning(default:4100) /* "unreferenced formal parameter" warning */