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.

3108 lines
105 KiB

  1. /*
  2. * Registry Management
  3. *
  4. * HTREGMNG.C
  5. *
  6. * Copyright (c) 1995 Microsoft Corporation
  7. *
  8. */
  9. #include "priv.h"
  10. #include "htregmng.h"
  11. #include "resource.h"
  12. #include "regapix.h"
  13. #include <filetype.h>
  14. #include <advpub.h>
  15. #include <mluisupp.h>
  16. // This file contains the auto-registration code, which smartly performs
  17. // the install/uninstall of registry keys and values. While an inf file
  18. // is sufficient most of the time, IE needs to be smart about what
  19. // sort of values to set, based upon certain conditions. An inf file
  20. // does not offer this depth of support. Additionally, IE requires
  21. // code to be run when it detects that it is not the default browser,
  22. // so it can make it the default browser. Any settings that determine
  23. // this should be placed here, rather than the inf file.
  24. //
  25. // This code is table driven. The idea is simple. You have a RegSet
  26. // which is the "Registry Set". The Registry Set indicates the
  27. // root key and contains a list of RegEntries. Each RegEntry
  28. // specifies a command, flags, key and value names, and optional data
  29. // that provides the essential info to set/change/delete a registry
  30. // value or key.
  31. //
  32. //
  33. // NOTE: NOTE: NOTE: NOTE: NOTE: NOTE: NOTE:
  34. //-------------------------------------------
  35. // Any new Icon check that uses HTReg_UrlIconProc that gets added
  36. // to any of the Assoc arrays and is REQUIRED for Default Browser check to
  37. // succeed has to be added to the c_rlAssoc_FixIcon[] array also.
  38. //
  39. // Make the tables more compact
  40. #define HKCR HKEY_CLASSES_ROOT
  41. #define HKLM HKEY_LOCAL_MACHINE
  42. #define HKCU HKEY_CURRENT_USER
  43. #define IDEFICON_STD 0
  44. #define IDEFICON_NEWS 1
  45. #define IDEFICON_MAIL 2
  46. #ifndef UNIX
  47. #define IEXPLORE_APP "IExplore"
  48. #define IEXPLORE_EXE "iexplore.exe"
  49. #define EXPLORER_EXE "explorer.exe"
  50. #define RUNDLL_CMD_FMT "rundll32.exe %s"
  51. #else
  52. #define IEXPLORE_APP "iexplorer"
  53. #define IEXPLORE_EXE "iexplorer"
  54. #define EXPLORER_EXE "explorer"
  55. #define RUNDLL_CMD_FMT "rundll32 %s"
  56. #endif
  57. BOOL InstallRegSet(const RegSet *prs, BOOL bDontIntrude);
  58. #ifndef UNIX
  59. const CHAR c_szIexploreKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE";
  60. #else
  61. const CHAR c_szIexploreKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORER";
  62. #endif
  63. #ifdef DEBUG
  64. /*----------------------------------------------------------
  65. Purpose: Return a string path composed of hkey\pszKey\pszValueName.
  66. Returns:
  67. Cond: --
  68. */
  69. LPTSTR
  70. Dbg_RegStr(
  71. IN const RegEntry * pre,
  72. IN LPTSTR pszBuf)
  73. {
  74. TCHAR szRoot[5];
  75. TCHAR szTempKey[MAXIMUM_SUB_KEY_LENGTH];
  76. TCHAR szTempValue[MAXIMUM_VALUE_NAME_LENGTH];
  77. ASSERT(pre);
  78. ASSERT(pszBuf);
  79. if (HKEY_CLASSES_ROOT == pre->hkeyRoot)
  80. {
  81. StrCpyN(szRoot, TEXT("HKCR"), ARRAYSIZE(szRoot));
  82. }
  83. else if (HKEY_CURRENT_USER == pre->hkeyRoot)
  84. {
  85. StrCpyN(szRoot, TEXT("HKCU"), ARRAYSIZE(szRoot));
  86. }
  87. else if (HKEY_LOCAL_MACHINE == pre->hkeyRoot)
  88. {
  89. StrCpyN(szRoot, TEXT("HKLM"), ARRAYSIZE(szRoot));
  90. }
  91. else
  92. {
  93. StrCpyN(szRoot, TEXT("????"), ARRAYSIZE(szRoot));
  94. ASSERT(0);
  95. }
  96. AnsiToTChar(pre->pszKey, szTempKey, ARRAYSIZE(szTempKey));
  97. szTempValue[0] = TEXT('\0');
  98. if (pre->pszValName)
  99. AnsiToTChar(pre->pszValName, szTempValue, ARRAYSIZE(szTempValue));
  100. ASSERT(lstrlen(pszBuf) < MAX_PATH);
  101. wnsprintf(pszBuf, MAX_PATH, TEXT("%s\\%hs\\%hs"), szRoot, szTempKey, szTempValue);
  102. return pszBuf;
  103. }
  104. #else
  105. #define Dbg_RegStr(x, y) 0
  106. #endif // DEBUG
  107. /*----------------------------------------------------------
  108. Purpose: Queries the registry for the location of the path
  109. of Internet Explorer and returns it in pszBuf.
  110. Returns: TRUE on success
  111. FALSE if path cannot be determined
  112. Cond: --
  113. */
  114. BOOL
  115. GetIEPath2(
  116. OUT LPSTR pszBuf,
  117. IN DWORD cchBuf,
  118. IN BOOL bInsertQuotes)
  119. {
  120. BOOL bRet = FALSE;
  121. HKEY hkey;
  122. *pszBuf = '\0';
  123. // Get the path of Internet Explorer
  124. if (NO_ERROR != RegOpenKeyA(HKEY_LOCAL_MACHINE, c_szIexploreKey, &hkey))
  125. {
  126. #ifndef UNIX
  127. TraceMsg(TF_ERROR, "InstallRegSet(): RegOpenKey( %s ) Failed", c_szIexploreKey) ;
  128. #endif
  129. }
  130. else
  131. {
  132. DWORD cbBrowser;
  133. DWORD dwType;
  134. if (bInsertQuotes)
  135. StrCatBuffA(pszBuf, "\"", cchBuf);
  136. cbBrowser = CbFromCchA(cchBuf - lstrlenA(" -nohome") - 4);
  137. if (NO_ERROR != SHQueryValueExA(hkey, "", NULL, &dwType,
  138. (LPBYTE)&pszBuf[bInsertQuotes?1:0], &cbBrowser))
  139. {
  140. TraceMsg(TF_ERROR, "InstallRegSet(): RegQueryValueEx() for Iexplore path failed");
  141. }
  142. else
  143. {
  144. bRet = TRUE;
  145. }
  146. if (bInsertQuotes)
  147. StrCatBuffA(pszBuf, "\"", cchBuf);
  148. RegCloseKey(hkey);
  149. }
  150. return bRet;
  151. }
  152. BOOL
  153. GetIEPath(
  154. OUT LPSTR pszBuf,
  155. IN DWORD cchBuf)
  156. {
  157. return GetIEPath2(pszBuf, cchBuf, TRUE);
  158. }
  159. /*----------------------------------------------------------
  160. Purpose: Queries the registry for the location of the path
  161. of the shell's Explorer and returns it in pszBuf.
  162. Returns: TRUE on success
  163. FALSE if path cannot be determined
  164. Cond: --
  165. */
  166. BOOL
  167. GetExplorerPath(
  168. OUT LPSTR pszBuf,
  169. IN DWORD cchBuf, DWORD dwType)
  170. {
  171. BOOL bRet;
  172. // Get the path of the Explorer
  173. if (dwType == REG_EXPAND_SZ)
  174. {
  175. StrCpyNA (pszBuf, "%SystemRoot%", cchBuf);
  176. bRet = TRUE;
  177. }
  178. else
  179. bRet = (0 < GetWindowsDirectoryA(pszBuf, cchBuf));
  180. if (bRet)
  181. {
  182. StrCatBuffA(pszBuf, "\\Explorer.exe", cchBuf);
  183. }
  184. return bRet;
  185. }
  186. // Callback messages
  187. #define RSCB_QUERY 1
  188. #define RSCB_INSTALL 2
  189. typedef BOOL (CALLBACK* RSPECPROC)(UINT nMsg, const RegEntry * pre, LPVOID pvData, DWORD dwData);
  190. // Win9x to NT5 migration generated file.
  191. #define MIGICONS "migicons.exe"
  192. /*----------------------------------------------------------
  193. Purpose: This callback sets the default icon to point to a
  194. given index in url.dll.
  195. Returns: varies
  196. Cond: --
  197. */
  198. BOOL
  199. CALLBACK
  200. HTReg_UrlIconProc(
  201. IN UINT nMsg,
  202. IN const RegEntry * pre,
  203. IN LPVOID pvData, OPTIONAL
  204. IN DWORD dwData)
  205. {
  206. BOOL bRet = TRUE;
  207. CHAR sz[MAX_PATH + 20]; // Need a bit extra
  208. LPCSTR pszPath = (LPCSTR) pvData;
  209. int cch;
  210. DWORD dwType; //local type.
  211. DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
  212. ASSERT(RSCB_QUERY == nMsg && pvData ||
  213. RSCB_INSTALL == nMsg && !pvData);
  214. if (!g_fRunningOnNT) {
  215. ASSERT(REG_EXPAND_SZ == pre->dwType);
  216. dwType = REG_SZ;
  217. } else
  218. dwType = (DWORD)pre->dwType;
  219. if (dwType == REG_EXPAND_SZ)
  220. StrCpyNA (sz, "%SystemRoot%\\system32", ARRAYSIZE(sz));
  221. else
  222. GetSystemDirectoryA(sz, SIZECHARS(sz));
  223. cch = lstrlenA(sz);
  224. // We still have to use url.dll as the source of the internet shortcut
  225. // icons because the icons need to still be valid on uninstall.
  226. wnsprintfA(&sz[cch], ARRAYSIZE(sz) - cch, "\\url.dll,%d", (int)pre->DUMMYUNION_MEMBER(lParam));
  227. switch (nMsg)
  228. {
  229. case RSCB_QUERY:
  230. if (0 != StrCmpNIA(sz, pszPath, dwData / SIZEOF(CHAR)) &&
  231. 0 != StrCmpIA(PathFindFileNameA(sz), PathFindFileNameA(pszPath)))
  232. {
  233. // Failed the Url.Dll test. Check if this is NT5. In that case
  234. // maybe the icons are in migicons.exe (Win9x to NT5 upgrade).
  235. if (g_bRunOnNT5 && StrStrIA(pszPath,MIGICONS)!= NULL)
  236. { // NT5 and 'migicons.exe' => upgrade. Set global to fix this.
  237. g_bNT5Upgrade = TRUE;
  238. }
  239. else
  240. {
  241. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s is %hs, expecting %hs", Dbg_RegStr(pre, szDbg), pszPath, sz);
  242. bRet = FALSE;
  243. }
  244. }
  245. break;
  246. case RSCB_INSTALL:
  247. if (NO_ERROR != SHSetValueA(pre->hkeyRoot, pre->pszKey,
  248. pre->pszValName, dwType,
  249. sz, CbFromCchA(lstrlenA(sz) + 1)))
  250. {
  251. TraceMsg(TF_ERROR, "InstallRegSet(): SHSetValue(%s) Failed", Dbg_RegStr(pre, szDbg));
  252. bRet = FALSE;
  253. }
  254. else
  255. {
  256. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
  257. }
  258. break;
  259. }
  260. return bRet;
  261. }
  262. /*----------------------------------------------------------
  263. Purpose: This callback sets the default icon to point to a
  264. given index in iexplore.exe
  265. Returns: varies
  266. Cond: --
  267. */
  268. BOOL
  269. CALLBACK
  270. HTReg_IEIconProc(
  271. IN UINT nMsg,
  272. IN const RegEntry * pre,
  273. IN LPVOID pvData, OPTIONAL
  274. IN DWORD dwData)
  275. {
  276. BOOL bRet = TRUE;
  277. CHAR sz[MAX_PATH + 20]; // Need a bit extra
  278. LPCSTR pszPath = (LPCSTR) pvData;
  279. int cch;
  280. DWORD dwType; //local type.
  281. DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
  282. ASSERT(RSCB_QUERY == nMsg && pvData ||
  283. RSCB_INSTALL == nMsg && !pvData);
  284. if (!g_fRunningOnNT) {
  285. // Sanity check that we don't coerce to REG_SZ wrongfully.
  286. // If you hit this assert, it means the table entry has the
  287. // wrong type in it.
  288. ASSERT(REG_EXPAND_SZ == pre->dwType || REG_SZ == pre->dwType);
  289. dwType = REG_SZ;
  290. } else
  291. dwType = (DWORD)pre->dwType;
  292. if (!GetIEPath2(sz, SIZECHARS(sz), FALSE))
  293. return FALSE;
  294. cch = lstrlenA(sz);
  295. wnsprintfA(&sz[cch], ARRAYSIZE(sz) - cch, ",%d", (int)pre->DUMMYUNION_MEMBER(lParam));
  296. switch (nMsg)
  297. {
  298. case RSCB_QUERY:
  299. if (0 != StrCmpNIA(sz, pszPath, dwData / SIZEOF(CHAR)) &&
  300. 0 != StrCmpA(PathFindFileNameA(sz), PathFindFileNameA(pszPath)))
  301. {
  302. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s is %hs, expecting %hs", Dbg_RegStr(pre, szDbg), pszPath, sz);
  303. bRet = FALSE;
  304. }
  305. break;
  306. case RSCB_INSTALL:
  307. if (NO_ERROR != SHSetValueA(pre->hkeyRoot, pre->pszKey,
  308. pre->pszValName, dwType,
  309. sz, CbFromCchA(lstrlenA(sz) + 1)))
  310. {
  311. TraceMsg(TF_ERROR, "InstallRegSet(): SHSetValue(%s) Failed", Dbg_RegStr(pre, szDbg));
  312. bRet = FALSE;
  313. }
  314. else
  315. {
  316. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
  317. }
  318. break;
  319. }
  320. return bRet;
  321. }
  322. /*----------------------------------------------------------
  323. Purpose: This callback sets the IExplore path.
  324. Returns: varies
  325. Cond: --
  326. */
  327. BOOL
  328. CALLBACK
  329. HTReg_IEPathProc(
  330. IN UINT nMsg,
  331. IN const RegEntry * pre,
  332. IN LPVOID pvData, OPTIONAL
  333. IN DWORD dwData)
  334. {
  335. BOOL bRet = TRUE;
  336. CHAR sz[MAX_PATH + 20]; // Need a bit extra
  337. CHAR szOther[MAX_PATH + 20]; // Need a bit extra
  338. LPCSTR pszPath = (LPCSTR) pvData;
  339. int cch;
  340. DWORD dwType;
  341. DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
  342. ASSERT(RSCB_QUERY == nMsg && pvData ||
  343. RSCB_INSTALL == nMsg && !pvData);
  344. ASSERT(REG_EXPAND_SZ == pre->dwType || REG_SZ == pre->dwType);
  345. if (!g_fRunningOnNT)
  346. {
  347. // Expand string is not supported on Win95
  348. dwType = REG_SZ;
  349. }
  350. else
  351. {
  352. dwType = pre->dwType;
  353. }
  354. if (GetIEPath(sz, SIZECHARS(sz))) {
  355. // sz contains the path as listed in AppPaths\IExplore.
  356. // NOTE NOTE: GetIEPath() uses the default value which has no
  357. // terminating ';'. Hence this check is not needed. Anyway, do it and
  358. // then convert to other form.
  359. cch = lstrlenA(sz) - 1;
  360. if (*sz && sz[cch] == ';')
  361. sz[cch] = '\0';
  362. // Convert this to LFN or SFN as the case may be.
  363. GetPathOtherFormA(sz, szOther, ARRAYSIZE(szOther));
  364. if (pre->DUMMYUNION_MEMBER(lParam))
  365. {
  366. StrCatBuffA(sz, (LPSTR)pre->DUMMYUNION_MEMBER(lParam), ARRAYSIZE(sz));
  367. StrCatBuffA(szOther, (LPSTR)pre->DUMMYUNION_MEMBER(lParam), ARRAYSIZE(szOther));
  368. }
  369. switch (nMsg)
  370. {
  371. case RSCB_QUERY:
  372. if ((0 != StrCmpNIA(pszPath, sz, dwData / SIZEOF(CHAR)))
  373. && (0 != StrCmpNIA(pszPath, szOther, dwData / SIZEOF(CHAR))))
  374. {
  375. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s string is \"%hs\", expecting \"%hs\"", Dbg_RegStr(pre, szDbg), pszPath, sz);
  376. bRet = FALSE;
  377. }
  378. break;
  379. case RSCB_INSTALL:
  380. if (NO_ERROR != SHSetValueA(pre->hkeyRoot, pre->pszKey,
  381. pre->pszValName, dwType,
  382. sz, CbFromCchA(lstrlenA(sz) + 1)))
  383. {
  384. TraceMsg(TF_ERROR, "InstallRegSet(): SHSetValue(%hs) Failed", pre->pszValName);
  385. bRet = FALSE;
  386. }
  387. else
  388. {
  389. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
  390. }
  391. break;
  392. }
  393. }
  394. return bRet;
  395. }
  396. /*----------------------------------------------------------
  397. Purpose: This callback checks for the existence of the string
  398. value "Exchange" at HKLM\Software\Microsoft. If it
  399. exists, the value is copied into the default value
  400. of HKLM\Software\Clients\Mail\Exchange\shell\open\command.
  401. This is for Athena. It only happens when setup is run,
  402. not when the browser checks to see if it is the default.
  403. Returns: varies
  404. Cond: --
  405. */
  406. BOOL
  407. CALLBACK
  408. HTReg_ExchangeProc(
  409. IN UINT nMsg,
  410. IN const RegEntry * pre,
  411. IN LPVOID pvData,
  412. IN DWORD dwData)
  413. {
  414. TCHAR sz[MAX_PATH+2]; // +2 because we may need to wrap the path in quotes.
  415. DWORD cbSize;
  416. switch (nMsg)
  417. {
  418. case RSCB_QUERY:
  419. // We shouldn't be called for this one
  420. ASSERT(0);
  421. break;
  422. case RSCB_INSTALL:
  423. // Does the Exchange value exist at "HKLM\Software\Microsoft"?
  424. cbSize = sizeof(sz);
  425. if (NO_ERROR == SHGetValue(HKEY_LOCAL_MACHINE,
  426. TEXT("Software\\Microsoft"), TEXT("Exchange"), NULL, sz, &cbSize))
  427. {
  428. // Yes; copy it to HKLM\Software\Clients\Mail\Exchange\shell\open\command
  429. TCHAR szT[MAX_PATH+2];
  430. // Wrap the path in quotes. Don't wrap any args though!
  431. StrCpyN(szT, sz, ARRAYSIZE(szT));
  432. PathProcessCommand(szT, sz, ARRAYSIZE(szT), PPCF_ADDQUOTES|PPCF_ADDARGUMENTS);
  433. // Set the size again
  434. cbSize = CbFromCch(lstrlen(sz)+1);
  435. SHSetValue(HKEY_LOCAL_MACHINE,
  436. TEXT("Software\\Clients\\Mail\\Exchange\\shell\\open\\command"),
  437. TEXT(""), REG_SZ, sz, cbSize);
  438. TraceMsg(TF_REGCHECK, "Copying \"%s\" to HKLM\\Software\\Clients\\Mail\\Exchange", sz);
  439. // Set any other settings in this condition too?
  440. if (pre->DUMMYUNION_MEMBER(lParam))
  441. InstallRegSet((const RegSet *)pre->DUMMYUNION_MEMBER(lParam), TRUE);
  442. // In OSR2 installs, the mailto handler will get out of
  443. // sync with the actual default mail client. (Athena installs
  444. // itself as the default mail client, but exchange remains
  445. // the mailto: handler.) In this case, if exchange is the
  446. // mailto: handler, change the default mail client to be
  447. // exchange.
  448. // Is Exchange the mailto handler?
  449. cbSize = SIZEOF(sz);
  450. if (NO_ERROR == SHGetValue(HKEY_CLASSES_ROOT, TEXT("mailto\\shell\\open\\command"),
  451. TEXT(""), NULL, sz, &cbSize) &&
  452. StrStrI(sz, TEXT("url.dll,MailToProtocolHandler")))
  453. {
  454. // Yes; make it be the default mail client too
  455. SHSetValue(HKEY_LOCAL_MACHINE, TEXT("Software\\Clients\\Mail"),
  456. TEXT(""), REG_SZ, TEXT("Exchange"), sizeof(TEXT("Exchange")));
  457. TraceMsg(TF_REGCHECK, "Setting Exchange to be the default mail client.");
  458. }
  459. }
  460. break;
  461. }
  462. return TRUE;
  463. }
  464. /*----------------------------------------------------------
  465. Purpose: Uninstall certain keys, as specified by pre->pszKey.
  466. We do not uninstall a key if the class\shell\open\command
  467. does not have iexplore.exe.
  468. If someone else registered themselves to add more
  469. verbs under class\shell (other than open) or class\shellex,
  470. then we remove everything but their keys.
  471. Returns: varies
  472. Cond: --
  473. */
  474. BOOL
  475. CALLBACK
  476. HTReg_UninstallProc(
  477. IN UINT nMsg,
  478. IN const RegEntry * pre,
  479. IN LPVOID pvData,
  480. IN DWORD dwData)
  481. {
  482. TCHAR szKey[MAX_PATH];
  483. TCHAR sz[MAX_PATH + 20]; // add some padding for arguments
  484. DWORD cbSize;
  485. switch (nMsg)
  486. {
  487. case RSCB_QUERY:
  488. // We shouldn't be called for this one
  489. ASSERT(0);
  490. break;
  491. case RSCB_INSTALL:
  492. ASSERT(pre->pszKey);
  493. // Does the shell\open\command value have a microsoft browser?
  494. wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("%hs\\shell\\open\\command"), pre->pszKey);
  495. cbSize = sizeof(sz);
  496. if (NO_ERROR == SHGetValue(pre->hkeyRoot, szKey, TEXT(""),
  497. NULL, sz, &cbSize) &&
  498. (StrStrI(sz, TEXT(IEXPLORE_EXE)) || StrStrI(sz, TEXT(EXPLORER_EXE))))
  499. {
  500. // Yes; proceed to prune this key of all of our values
  501. TraceMsg(TF_REGCHECK, "Pruning HKCR\\%hs", pre->pszKey);
  502. ASSERT(pre->DUMMYUNION_MEMBER(lParam));
  503. InstallRegSet((const RegSet *)pre->DUMMYUNION_MEMBER(lParam), FALSE);
  504. }
  505. break;
  506. }
  507. return TRUE;
  508. }
  509. // NOTE: these are ANSI strings by design.
  510. const DWORD c_dwEditFlags2 = FTA_Show;
  511. const CHAR c_szTelnetHandler[] = "url.dll,TelnetProtocolHandler %l";
  512. const CHAR c_szMailToHandler[] = "url.dll,MailToProtocolHandler %l";
  513. const CHAR c_szNewsHandler[] = "url.dll,NewsProtocolHandler %l";
  514. const CHAR c_szFileHandler[] = "url.dll,FileProtocolHandler %l";
  515. const CHAR c_szOpenURL[] = "url.dll,OpenURL %l";
  516. const CHAR c_szOpenURLNash[] = "shdocvw.dll,OpenURL %l";
  517. const CHAR c_szURL[] = "url.dll";
  518. const CHAR c_szShdocvw[] = "shdocvw.dll";
  519. const CHAR c_szCheckAssnSwitch[] = "Software\\Microsoft\\Internet Explorer\\Main";
  520. const CHAR c_szDDE_Default[] = "\"%1\",,-1,0,,,,";
  521. const CHAR c_szDDE_FileDefault[] = "\"file://%1\",,-1,,,,,";
  522. // Note (scotth): a lot of the strings below have substrings that
  523. // are repeated over and over and over again. Should add some
  524. // smarter RC_ values that will concatenate the common strings
  525. // together to save data space.
  526. const CHAR c_szHTTP[] = "http";
  527. const CHAR c_szHTTPDefIcon[] = "http\\DefaultIcon";
  528. const CHAR c_szHTTPOpenCmd[] = "http\\shell\\open\\command";
  529. const CHAR c_szHTTPDdeexec[] = "http\\shell\\open\\ddeexec";
  530. const CHAR c_szHTTPDdeTopic[] = "http\\shell\\open\\ddeexec\\Topic";
  531. const CHAR c_szHTTPDdeApp[] = "http\\shell\\open\\ddeexec\\Application";
  532. const CHAR c_szHTTPS[] = "https";
  533. const CHAR c_szHTTPSDefIcon[] = "https\\DefaultIcon";
  534. const CHAR c_szHTTPSOpenCmd[] = "https\\shell\\open\\command";
  535. const CHAR c_szHTTPSDdeexec[] = "https\\shell\\open\\ddeexec";
  536. const CHAR c_szHTTPSDdeTopic[] = "https\\shell\\open\\ddeexec\\Topic";
  537. const CHAR c_szHTTPSDdeApp[] = "https\\shell\\open\\ddeexec\\Application";
  538. const CHAR c_szFTP[] = "ftp";
  539. const CHAR c_szFTPDefIcon[] = "ftp\\DefaultIcon";
  540. const CHAR c_szFTPOpenCmd[] = "ftp\\shell\\open\\command";
  541. const CHAR c_szFTPDdeexec[] = "ftp\\shell\\open\\ddeexec";
  542. const CHAR c_szFTPDdeTopic[] = "ftp\\shell\\open\\ddeexec\\Topic";
  543. const CHAR c_szFTPDdeApp[] = "ftp\\shell\\open\\ddeexec\\Application";
  544. const CHAR c_szFTPDdeifExec[] = "ftp\\shell\\open\\ddeexec\\ifExec";
  545. const CHAR c_szGOPHER[] = "gopher";
  546. const CHAR c_szGOPHERDefIcon[] = "gopher\\DefaultIcon";
  547. const CHAR c_szGOPHEROpenCmd[] = "gopher\\shell\\open\\command";
  548. const CHAR c_szGOPHERDdeexec[] = "gopher\\shell\\open\\ddeexec";
  549. const CHAR c_szGOPHERDdeTopic[] = "gopher\\shell\\open\\ddeexec\\Topic";
  550. const CHAR c_szGOPHERDdeApp[] = "gopher\\shell\\open\\ddeexec\\Application";
  551. const CHAR c_szMailTo[] = "mailto";
  552. const CHAR c_szMailToDefIcon[] = "mailto\\DefaultIcon";
  553. const CHAR c_szMailToOpenCmd[] = "mailto\\shell\\open\\command";
  554. const CHAR c_szTelnet[] = "telnet";
  555. const CHAR c_szTelnetDefIcon[] = "telnet\\DefaultIcon";
  556. const CHAR c_szTelnetOpenCmd[] = "telnet\\shell\\open\\command";
  557. const CHAR c_szRLogin[] = "rlogin";
  558. const CHAR c_szRLoginDefIcon[] = "rlogin\\DefaultIcon";
  559. const CHAR c_szRLoginOpenCmd[] = "rlogin\\shell\\open\\command";
  560. const CHAR c_szTN3270[] = "tn3270";
  561. const CHAR c_szTN3270DefIcon[] = "tn3270\\DefaultIcon";
  562. const CHAR c_szTN3270OpenCmd[] = "tn3270\\shell\\open\\command";
  563. const CHAR c_szNews[] = "news";
  564. const CHAR c_szNewsDefIcon[] = "news\\DefaultIcon";
  565. const CHAR c_szNewsOpenCmd[] = "news\\shell\\open\\command";
  566. const CHAR c_szFile[] = "file";
  567. const CHAR c_szFileDefIcon[] = "file\\DefaultIcon";
  568. const CHAR c_szFileOpenCmd[] = "file\\shell\\open\\command";
  569. const CHAR c_szHTMDefIcon[] = "htmlfile\\DefaultIcon";
  570. const CHAR c_szHTMShell[] = "htmlfile\\shell";
  571. const CHAR c_szHTMOpen[] = "htmlfile\\shell\\open";
  572. const CHAR c_szHTMOpenCmd[] = "htmlfile\\shell\\open\\command";
  573. const CHAR c_szHTMOpenDdeexec[] = "htmlfile\\shell\\open\\ddeexec";
  574. const CHAR c_szHTMOpenDdeTopic[] = "htmlfile\\shell\\open\\ddeexec\\Topic";
  575. const CHAR c_szHTMOpenDdeApp[] = "htmlfile\\shell\\open\\ddeexec\\Application";
  576. const CHAR c_szMHTMDefIcon[] = "mhtmlfile\\DefaultIcon";
  577. const CHAR c_szMHTMShell[] = "mhtmlfile\\shell";
  578. const CHAR c_szMHTMOpen[] = "mhtmlfile\\shell\\open";
  579. const CHAR c_szMHTMOpenCmd[] = "mhtmlfile\\shell\\open\\command";
  580. const CHAR c_szMHTMOpenDdeexec[] = "mhtmlfile\\shell\\open\\ddeexec";
  581. const CHAR c_szMHTMOpenDdeTopic[] = "mhtmlfile\\shell\\open\\ddeexec\\Topic";
  582. const CHAR c_szMHTMOpenDdeApp[] = "mhtmlfile\\shell\\open\\ddeexec\\Application";
  583. const CHAR c_szOpenNew[] = "opennew";
  584. const CHAR c_szHTMOpenNew[] = "htmlfile\\shell\\opennew";
  585. const CHAR c_szHTMOpenNewCmd[] = "htmlfile\\shell\\opennew\\command";
  586. const CHAR c_szHTMOpenNewDdeexec[] = "htmlfile\\shell\\opennew\\ddeexec";
  587. const CHAR c_szHTMOpenNewDdeIfExec[] = "htmlfile\\shell\\opennew\\ddeexec\\IfExec";
  588. const CHAR c_szHTMOpenNewDdeTopic[] = "htmlfile\\shell\\opennew\\ddeexec\\Topic";
  589. const CHAR c_szHTMOpenNewDdeApp[] = "htmlfile\\shell\\opennew\\ddeexec\\Application";
  590. const CHAR c_szMHTMOpenNew[] = "mhtmlfile\\shell\\opennew";
  591. const CHAR c_szMHTMOpenNewCmd[] = "mhtmlfile\\shell\\opennew\\command";
  592. const CHAR c_szMHTMOpenNewDdeexec[] = "mhtmlfile\\shell\\opennew\\ddeexec";
  593. const CHAR c_szMHTMOpenNewDdeIfExec[] = "mhtmlfile\\shell\\opennew\\ddeexec\\IfExec";
  594. const CHAR c_szMHTMOpenNewDdeTopic[] = "mhtmlfile\\shell\\opennew\\ddeexec\\Topic";
  595. const CHAR c_szMHTMOpenNewDdeApp[] = "mhtmlfile\\shell\\opennew\\ddeexec\\Application";
  596. const CHAR c_szIntShcut[] = "InternetShortcut";
  597. const CHAR c_szIntShcutDefIcon[] = "InternetShortcut\\DefaultIcon";
  598. const CHAR c_szIntShcutCLSID[] = "InternetShortcut\\CLSID";
  599. const CHAR c_szIntShcutOpen[] = "InternetShortcut\\shell\\open";
  600. const CHAR c_szIntShcutOpenCmd[] = "InternetShortcut\\shell\\open\\command";
  601. const CHAR c_szIntShcutIconHandler[] = "InternetShortcut\\shellex\\IconHandler";
  602. const CHAR c_szIntShcutPrshtHandler[]= "InternetShortcut\\shellex\\PropertySheetHandlers\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}";
  603. const CHAR c_szIntShcutPropHandler[] = "InternetShortcut\\shellex\\PropertyHandler";
  604. const CHAR c_szIntShcutCMHandler[] = "InternetShortcut\\shellex\\ContextMenuHandlers\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}";
  605. const CHAR c_szCLSIDCmdFile[] = "{57651662-CE3E-11D0-8D77-00C04FC99D61}";
  606. const CHAR c_szCLSIDIntshcut[] = "{FBF23B40-E3F0-101B-8488-00AA003E56F8}";
  607. const CHAR c_szCLSIDURLExecHook[] = "{AEB6717E-7E19-11d0-97EE-00C04FD91972}";
  608. const CHAR c_szIntshcutInproc[] = "CLSID\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}\\InProcServer32";
  609. const CHAR c_szIEFrameAuto[] = "CLSID\\{0002DF01-0000-0000-C000-000000000046}\\LocalServer32";
  610. const CHAR c_szIENameSpaceOpen[] = "CLSID\\{FBF23B42-E3F0-101B-8488-00AA003E56F8}\\shell\\open\\command";
  611. const CHAR c_szCLSIDURLRoot[] = "CLSID\\{3DC7A020-0ACD-11CF-A9BB-00AA004AE837}";
  612. const CHAR c_szIntshcutMayChange[] = "CLSID\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}\\shellex\\MayChangeDefaultMenu";
  613. //
  614. // General associations shared across browser-only and full-shell
  615. //
  616. const RegEntry c_rlAssoc[] = {
  617. // HTTP
  618. { RC_ADD, REF_NOTNEEDED, HKCR, c_szHTTP, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_HTTPNAME) },
  619. { RC_ADD, REF_NORMAL, HKCR, c_szHTTP, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  620. { RC_ADD, REF_NORMAL, HKCR, c_szHTTP, "URL Protocol", REG_SZ, 1, "" },
  621. { RC_CALLBACK, REF_NOTNEEDED
  622. |REF_DONTINTRUDE, HKCR, c_szHTTPDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  623. // HTTPS
  624. { RC_ADD, REF_NOTNEEDED, HKCR, c_szHTTPS, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_HTTPSNAME) },
  625. { RC_ADD, REF_NORMAL, HKCR, c_szHTTPS, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  626. { RC_ADD, REF_NORMAL, HKCR, c_szHTTPS, "URL Protocol", REG_SZ, 1, "" },
  627. { RC_CALLBACK, REF_NOTNEEDED|REF_DONTINTRUDE, HKCR, c_szHTTPSDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  628. // FTP
  629. { RC_ADD, REF_NOTNEEDED, HKCR, c_szFTP, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_FTPNAME) },
  630. { RC_ADD, REF_NORMAL, HKCR, c_szFTP, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  631. { RC_ADD, REF_NORMAL, HKCR, c_szFTP, "URL Protocol", REG_SZ, 1, "" },
  632. { RC_CALLBACK, REF_NOTNEEDED|REF_DONTINTRUDE, HKCR, c_szFTPDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  633. // Gopher
  634. { RC_ADD, REF_NOTNEEDED, HKCR, c_szGOPHER, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_GOPHERNAME) },
  635. { RC_ADD, REF_NORMAL, HKCR, c_szGOPHER, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  636. { RC_ADD, REF_NORMAL, HKCR, c_szGOPHER, "URL Protocol", REG_SZ, 1, "" },
  637. { RC_CALLBACK, REF_NOTNEEDED|REF_DONTINTRUDE, HKCR, c_szGOPHERDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  638. // Telnet
  639. { RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_TELNETNAME) },
  640. { RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  641. { RC_ADD, REF_IFEMPTY, HKCR, c_szTelnet, "URL Protocol", REG_SZ, 1, "" },
  642. { RC_CALLBACK, REF_IFEMPTY, HKCR, c_szTelnetDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  643. { RC_RUNDLL, REF_IFEMPTY, HKCR, c_szTelnetOpenCmd, "", REG_SZ, sizeof(c_szTelnetHandler), c_szTelnetHandler },
  644. // RLogin
  645. { RC_ADD, REF_IFEMPTY, HKCR, c_szRLogin, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_RLOGINNAME) },
  646. { RC_ADD, REF_IFEMPTY, HKCR, c_szRLogin, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  647. { RC_ADD, REF_IFEMPTY, HKCR, c_szRLogin, "URL Protocol", REG_SZ, 1, "" },
  648. { RC_CALLBACK, REF_IFEMPTY, HKCR, c_szRLoginDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  649. { RC_RUNDLL, REF_IFEMPTY, HKCR, c_szRLoginOpenCmd, "", REG_SZ, sizeof(c_szTelnetHandler), c_szTelnetHandler },
  650. // TN3270
  651. { RC_ADD, REF_IFEMPTY, HKCR, c_szTN3270, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_TN3270NAME) },
  652. { RC_ADD, REF_IFEMPTY, HKCR, c_szTN3270, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  653. { RC_ADD, REF_IFEMPTY, HKCR, c_szTN3270, "URL Protocol", REG_SZ, 1, "" },
  654. { RC_CALLBACK, REF_IFEMPTY, HKCR, c_szTN3270DefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  655. { RC_RUNDLL, REF_IFEMPTY, HKCR, c_szTN3270OpenCmd, "", REG_SZ, sizeof(c_szTelnetHandler), c_szTelnetHandler },
  656. // Mailto protocol
  657. { RC_ADD, REF_IFEMPTY, HKCR, c_szMailTo, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_MAILTONAME) },
  658. { RC_ADD, REF_IFEMPTY, HKCR, c_szMailTo, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  659. { RC_ADD, REF_IFEMPTY, HKCR, c_szMailTo, "URL Protocol", REG_SZ, 1, "" },
  660. { RC_CALLBACK, REF_IFEMPTY, HKCR, c_szMailToDefIcon, "", REG_EXPAND_SZ, IDEFICON_MAIL, HTReg_UrlIconProc },
  661. { RC_RUNDLL, REF_IFEMPTY, HKCR, c_szMailToOpenCmd, "", REG_SZ, sizeof(c_szMailToHandler), c_szMailToHandler },
  662. // News protocol
  663. { RC_ADD, REF_IFEMPTY, HKCR, c_szNews, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_NEWSNAME) },
  664. { RC_ADD, REF_IFEMPTY, HKCR, c_szNews, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  665. { RC_ADD, REF_IFEMPTY, HKCR, c_szNews, "URL Protocol", REG_SZ, 1, "" },
  666. { RC_CALLBACK, REF_IFEMPTY, HKCR, c_szNewsDefIcon, "", REG_EXPAND_SZ, IDEFICON_NEWS, HTReg_UrlIconProc },
  667. { RC_RUNDLL, REF_IFEMPTY, HKCR, c_szNewsOpenCmd, "", REG_SZ, sizeof(c_szNewsHandler), c_szNewsHandler },
  668. // Internet shortcut
  669. { RC_ADD, REF_NORMAL, HKCR, ".url", "", REG_SZ, sizeof(c_szIntShcut), c_szIntShcut },
  670. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcut, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_INTSHNAME) },
  671. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szIntShcut, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  672. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcut, "IsShortcut", REG_SZ, 1, "" },
  673. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcut, "NeverShowExt", REG_SZ, 1, "" },
  674. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutCLSID, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  675. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szIntShcutDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  676. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutIconHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  677. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutPrshtHandler, "", REG_SZ, 1, "" },
  678. { RC_ADD, REF_NORMAL, HKCR, "CLSID\\{FBF23B40-E3F0-101B-8488-00AA003E56F8}", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_INTSHNAME) },
  679. { RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "", REG_SZ, sizeof(c_szShdocvw), c_szShdocvw },
  680. { RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "ThreadingModel", REG_SZ, sizeof("Apartment"), "Apartment" },
  681. { RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "LoadWithoutCOM", REG_SZ, 1, ""},
  682. // HTM file type
  683. { RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szHTMDefIcon, "", REG_SZ, (LPARAM)1, HTReg_IEIconProc },
  684. // MHTML file type
  685. { RC_CALLBACK, REF_NOTNEEDED, HKCR, c_szMHTMDefIcon, "", REG_SZ, (LPARAM)22, HTReg_IEIconProc },
  686. };
  687. const RegSet c_rsAssoc = {
  688. ARRAYSIZE(c_rlAssoc),
  689. c_rlAssoc
  690. };
  691. //
  692. // .htm, .html associations for full-shell and browser-only installs
  693. //
  694. // This is run when the browser is opened, and considered a requirement
  695. // to make IE be the default browser.
  696. #ifdef UNIX
  697. const RegEntry c_rlAssocHTM[] = {
  698. #else
  699. const RegList c_rlAssocHTM = {
  700. #endif
  701. // .html
  702. { RC_ADD, REF_DONTINTRUDE, HKCR, ".htm", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
  703. { RC_ADD, REF_DONTINTRUDE, HKCR, ".htm", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
  704. { RC_ADD, REF_DONTINTRUDE, HKCR, ".html", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
  705. { RC_ADD, REF_DONTINTRUDE, HKCR, ".html", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
  706. };
  707. const RegSet c_rsAssocHTM = {
  708. ARRAYSIZE(c_rlAssocHTM),
  709. c_rlAssocHTM
  710. };
  711. // This is the minimum set that is queried every time a shell window opens.
  712. // WARNING: this should be small to reduce the time it takes to open a folder.
  713. // This is needed just to insure webview works.
  714. //
  715. const RegEntry c_rlAssocHTM_WV[] = {
  716. // .html
  717. { RC_ADD, REF_IFEMPTY, HKCR, ".htm", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
  718. { RC_ADD, REF_IFEMPTY, HKCR, ".htm", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
  719. { RC_ADD, REF_IFEMPTY, HKCR, ".html", "", REG_SZ, sizeof("htmlfile"), "htmlfile" },
  720. { RC_ADD, REF_IFEMPTY, HKCR, ".html", "Content Type", REG_SZ, sizeof("text/html"), "text/html" },
  721. };
  722. const RegSet c_rsAssocHTM_WV = {
  723. ARRAYSIZE(c_rlAssocHTM_WV),
  724. c_rlAssocHTM_WV
  725. };
  726. //
  727. // Browser-only specific association settings
  728. //
  729. const RegEntry c_rlAssoc_Alone[] = {
  730. // HTTP
  731. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  732. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  733. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  734. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  735. // HTTPS
  736. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPSOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  737. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  738. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  739. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  740. // FTP
  741. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
  742. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  743. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  744. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  745. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeifExec, "", REG_SZ, sizeof("*"), "*" },
  746. // Gopher
  747. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szGOPHEROpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  748. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  749. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  750. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  751. // File protocol
  752. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFile, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_FILENAME) },
  753. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFile, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  754. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFile, "URL Protocol", REG_SZ, 1, "" },
  755. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFileDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc },
  756. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFileOpenCmd, "", REG_SZ, sizeof(c_szFileHandler), c_szFileHandler },
  757. // .htm
  758. //
  759. // APPCOMPAT:
  760. // HTMOpenCmd needs to be REG_SZ because Office97 reads it out using RegQueryValue.
  761. // WebFerret requires the string to be of type REG_SZ.
  762. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  763. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
  764. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  765. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  766. // .mht, .mhtml
  767. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szMHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  768. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
  769. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  770. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  771. // Internet shortcut
  772. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
  773. // Other stuff
  774. { RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURLNash), c_szOpenURLNash },
  775. { RC_CALLBACK, REF_NORMAL, HKCR, c_szIEFrameAuto, "", REG_SZ, 0, HTReg_IEPathProc },
  776. { RC_CALLBACK, REF_NORMAL, HKCR, c_szIENameSpaceOpen, "", REG_SZ, 0, HTReg_IEPathProc },
  777. };
  778. const RegSet c_rsAssoc_Alone = {
  779. ARRAYSIZE(c_rlAssoc_Alone),
  780. c_rlAssoc_Alone
  781. };
  782. // The reg entries for the browser only case for http, https, and ftp are duplicated here
  783. const RegEntry c_rlAssoc_Quick[] = {
  784. // HTTP
  785. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  786. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  787. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  788. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  789. // HTTPS
  790. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPSOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  791. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  792. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  793. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  794. // FTP
  795. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
  796. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  797. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  798. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  799. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeifExec, "", REG_SZ, sizeof("*"), "*" },
  800. };
  801. const RegSet c_rsAssoc_Quick = {
  802. ARRAYSIZE(c_rlAssoc_Quick),
  803. c_rlAssoc_Quick
  804. };
  805. //
  806. // Full-shell specific association settings
  807. //
  808. const RegEntry c_rlAssoc_Full[] = {
  809. // HTTP
  810. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  811. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  812. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
  813. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  814. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  815. // HTTPS
  816. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szHTTPSOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  817. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  818. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
  819. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  820. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  821. // FTP
  822. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szFTPOpenCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
  823. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  824. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
  825. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  826. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  827. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szFTPDdeifExec, "", REG_SZ, sizeof("*"), "*" },
  828. // Gopher
  829. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szGOPHEROpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  830. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default },
  831. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
  832. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  833. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  834. // .htm
  835. //
  836. // APPCOMPAT:
  837. // HTMOpenCmd needs to be REG_SZ because Office97 reads it out using RegQueryValue.
  838. // WebFerret requires the string to be of type REG_SZ.
  839. // Visual Source Safe reads the Ddeexec string, puts a file in the %1 (NOT %l!),
  840. // and performs a dde transaction, so we are pretty much stuck with the "file:%1,,-1,,,,," string now.
  841. //
  842. { RC_ADD, REF_NORMAL, HKCR, c_szHTMShell, "", REG_SZ, sizeof(c_szOpenNew), c_szOpenNew },
  843. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpen, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPENSAME)},
  844. { RC_CALLBACK, REF_NORMAL, HKCR, c_szHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  845. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
  846. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
  847. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  848. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  849. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMShell, "", REG_SZ, sizeof(c_szOpenNew), c_szOpenNew },
  850. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNew, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPEN)},
  851. { RC_CALLBACK, REF_NORMAL, HKCR, c_szHTMOpenNewCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
  852. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "", REG_SZ, sizeof(c_szDDE_Default), c_szDDE_Default},
  853. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeIfExec, "", REG_SZ, sizeof("*"), "*"},
  854. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
  855. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  856. { RC_ADD, REF_NORMAL, HKCR, c_szHTMOpenNewDdeTopic, "", REG_SZ, sizeof("WWW_OpenURLNewWindow"), "WWW_OpenURLNewWindow" },
  857. // .mht, .mhtml
  858. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpen, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPENSAME)},
  859. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szMHTMOpenCmd, "", REG_SZ, (LPARAM)" -nohome", HTReg_IEPathProc },
  860. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
  861. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  862. { RC_ADD, REF_DONTINTRUDE, HKCR, c_szMHTMOpenDdeTopic, "", REG_SZ, sizeof("WWW_OpenURL"), "WWW_OpenURL" },
  863. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNew, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_OPEN)},
  864. { RC_CALLBACK, REF_NORMAL, HKCR, c_szMHTMOpenNewCmd, "", REG_SZ, (LPARAM)" %1", HTReg_IEPathProc },
  865. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "", REG_SZ, sizeof(c_szDDE_FileDefault), c_szDDE_FileDefault },
  866. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeIfExec, "", REG_SZ, sizeof("*"), "*"},
  867. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 1, "" },
  868. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeApp, "", REG_SZ, sizeof(IEXPLORE_APP), IEXPLORE_APP },
  869. { RC_ADD, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeTopic, "", REG_SZ, sizeof("WWW_OpenURLNewWindow"), "WWW_OpenURLNewWindow" },
  870. // Internet shortcut
  871. { RC_ADD, REF_NORMAL, HKCR, c_szCLSIDURLRoot, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
  872. { RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURLNash), c_szOpenURLNash },
  873. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutOpen, "CLSID", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  874. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutOpen, "LegacyDisable", REG_SZ, 1, ""},
  875. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
  876. { RC_ADD, REF_NORMAL, HKCR, c_szIntshcutMayChange, "", REG_SZ, 1, "" },
  877. { RC_ADD, REF_NORMAL, HKCR, c_szIntShcutPropHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  878. // add ourselves to the applications key
  879. { RC_CALLBACK, REF_NORMAL, HKCR, "Applications\\iexplore.exe\\shell\\open\\command", "", REG_SZ, (LPARAM)" ""%1""", HTReg_IEPathProc},
  880. // Other stuff
  881. { RC_CALLBACK, REF_NORMAL, HKCR, c_szIEFrameAuto, "", REG_SZ, 0, HTReg_IEPathProc },
  882. };
  883. const RegSet c_rsAssoc_Full = {
  884. ARRAYSIZE(c_rlAssoc_Full),
  885. c_rlAssoc_Full
  886. };
  887. //
  888. // On upgrading from Win9x to NT5, the icons are shifted to newly created
  889. // file called "migicons.exe". This breaks our Assoc checks. Hence this is
  890. // a list of all HTReg_UrlIconProc checks from the various Assoc arrays that
  891. // MUST BELONG TO US FOR US TO BE DEFAULT BROWSER (REF_NOTNEEDED and
  892. // REF_IFEMPTY ==> not used for check purposes).
  893. // This list is used to fix the icons.
  894. //
  895. // NOTE: NOTE: NOTE: NOTE: NOTE: NOTE: NOTE:
  896. // Any new Icon check that uses HTReg_UrlIconProc that gets added
  897. // to any of the Assoc arrays and is REQUIRED for Default Browser check to
  898. // succeed has to be added here also.
  899. //
  900. const RegEntry c_rlAssoc_FixIcon[] = {
  901. // Icon checks from c_rlAssoc that are essential for us to be Default
  902. // Browser
  903. { RC_CALLBACK, REF_DONTINTRUDE, HKCR, c_szIntShcutDefIcon, "", REG_EXPAND_SZ, IDEFICON_STD, HTReg_UrlIconProc }
  904. };
  905. const RegSet c_rsAssoc_FixIcon = {
  906. ARRAYSIZE(c_rlAssoc_FixIcon),
  907. c_rlAssoc_FixIcon
  908. };
  909. //
  910. // General browser-only settings
  911. //
  912. const CHAR c_szCLSIDMIME[] = "{FBF23B41-E3F0-101B-8488-00AA003E56F8}";
  913. const CHAR c_szIEOnDesktop[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\{FBF23B42-E3F0-101B-8488-00AA003E56F8}";
  914. const CHAR c_szShellExecHook[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellExecuteHooks";
  915. const CHAR c_szFileTypesHook[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileTypesPropertySheetHook";
  916. const RegEntry c_rlGeneral_Alone[] = {
  917. { RC_ADD, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
  918. { RC_ADD, REF_NORMAL, HKLM, c_szFileTypesHook, "", REG_SZ, sizeof(c_szCLSIDMIME), c_szCLSIDMIME },
  919. // URL Exec Hook (CLSID_URLExecHook) (this replaces the old overloaded intshcut CLSID)
  920. { RC_DEL, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDIntshcut, REG_SZ, 1, "" },
  921. { RC_ADD, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDURLExecHook, REG_SZ, 1, "" },
  922. { RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_URLEXECHOOK) },
  923. { RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "", REG_SZ, sizeof("url.dll"), "url.dll" },
  924. { RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "ThreadingModel", REG_SZ, sizeof("Apartment"), "Apartment" },
  925. };
  926. const RegSet c_rsGeneral_Alone = {
  927. ARRAYSIZE(c_rlGeneral_Alone),
  928. c_rlGeneral_Alone
  929. };
  930. //
  931. // General full-shell only settings
  932. //
  933. const RegEntry c_rlGeneral_Full[] = {
  934. { RC_DEL, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, NULL },
  935. { RC_DEL, REF_NUKE, HKLM, c_szFileTypesHook, "", REG_SZ, sizeof(c_szCLSIDMIME), c_szCLSIDMIME },
  936. // URL Exec Hook (this replaces the old overloaded intshcut CLSID)
  937. { RC_DEL, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDIntshcut, REG_SZ, 1, "" },
  938. { RC_ADD, REF_NORMAL, HKLM, c_szShellExecHook, c_szCLSIDURLExecHook, REG_SZ, 1, "" },
  939. { RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_URLEXECHOOK) },
  940. { RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "", REG_SZ, sizeof("shell32.dll"), "shell32.dll" },
  941. { RC_ADD, REF_NORMAL, HKCR, "CLSID\\{AEB6717E-7E19-11d0-97EE-00C04FD91972}\\InProcServer32", "ThreadingModel", REG_SZ, sizeof("Apartment"), "Apartment" },
  942. };
  943. const RegSet c_rsGeneral_Full = {
  944. ARRAYSIZE(c_rlGeneral_Full),
  945. c_rlGeneral_Full
  946. };
  947. // XP start menu
  948. // Note: the IE start menu reg entries are created in ie.inx, this table is only needed
  949. // to restore IE as default browser in the start menu (as a result of the user prompts)
  950. const RegEntry c_rlStartMenu_XP[] = {
  951. // make IE the default internet browser for this machine's Start Menu
  952. { RC_ADD, REF_NORMAL, HKLM, "Software\\Clients\\StartMenuInternet", "", REG_SZ, 0, "IEXPLORE.EXE" },
  953. };
  954. const RegSet c_rsStartMenu_XP = {
  955. ARRAYSIZE(c_rlStartMenu_XP),
  956. c_rlStartMenu_XP
  957. };
  958. const RegEntry c_rlStartMenu_XP_CU[] = {
  959. // make IE the default internet browser for this user's Start Menu
  960. { RC_ADD, REF_NORMAL, HKCU, "Software\\Clients\\StartMenuInternet", "", REG_SZ, 0, "IEXPLORE.EXE" },
  961. };
  962. const RegSet c_rsStartMenu_XP_CU = {
  963. ARRAYSIZE(c_rlStartMenu_XP_CU),
  964. c_rlStartMenu_XP_CU
  965. };
  966. /*
  967. * S P E C I A L D Y N A M I C S E T T I N G S
  968. *
  969. */
  970. #define SZ_EXMAILTO "Software\\Clients\\Mail\\Exchange\\Protocols\\Mailto"
  971. const RegEntry c_rlExchange[] = {
  972. { RC_ADD, REF_NORMAL, HKLM, "Software\\Clients\\Mail\\Exchange", "", REG_SZ, 0, MAKEINTRESOURCE(IDS_EXCHANGE) },
  973. { RC_ADD, REF_IFEMPTY, HKLM, SZ_EXMAILTO, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_MAILTONAME) },
  974. { RC_ADD, REF_IFEMPTY, HKLM, SZ_EXMAILTO, "EditFlags", REG_DWORD, sizeof(c_dwEditFlags2), &c_dwEditFlags2 },
  975. { RC_ADD, REF_IFEMPTY, HKLM, SZ_EXMAILTO, "URL Protocol", REG_SZ, 1, "" },
  976. { RC_CALLBACK, REF_IFEMPTY, HKLM, SZ_EXMAILTO "\\DefaultIcon", "", REG_EXPAND_SZ, IDEFICON_MAIL, HTReg_UrlIconProc },
  977. { RC_RUNDLL, REF_IFEMPTY, HKLM, SZ_EXMAILTO "\\Shell\\Open\\Command", "", REG_SZ, sizeof(c_szMailToHandler), c_szMailToHandler },
  978. };
  979. const RegSet c_rsExchange = {
  980. ARRAYSIZE(c_rlExchange),
  981. c_rlExchange
  982. };
  983. #ifdef UNIX
  984. const RegEntry c_rlAthena[] = {
  985. #else
  986. const RegList c_rlAthena = {
  987. #endif
  988. { RC_CALLBACK, REF_NORMAL, HKLM, "", "", REG_SZ, (LPARAM)&c_rsExchange, HTReg_ExchangeProc },
  989. };
  990. const RegSet c_rsAthena = {
  991. ARRAYSIZE(c_rlAthena),
  992. c_rlAthena
  993. };
  994. /*
  995. * U N I N S T A L L S E T T I N G S
  996. *
  997. */
  998. // Protocol-specific uninstall (for both full-shell and browser-only)
  999. const RegEntry c_rlUnHTTP[] = {
  1000. { RC_DEL, REF_NORMAL, HKCR, c_szHTTP, "URL Protocol", REG_SZ, 0, NULL },
  1001. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPDefIcon, "", REG_SZ, 0, NULL },
  1002. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeApp, "", REG_SZ, 0, NULL },
  1003. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeTopic, "", REG_SZ, 0, NULL },
  1004. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeexec, "", REG_SZ, 0, NULL },
  1005. { RC_DEL, REF_PRUNE, HKCR, c_szHTTPOpenCmd, "", REG_SZ, 0, NULL },
  1006. { RC_DEL, REF_EDITFLAGS, HKCR, c_szHTTP, "", REG_SZ, 0, NULL },
  1007. };
  1008. const RegSet c_rsUnHTTP = {
  1009. ARRAYSIZE(c_rlUnHTTP),
  1010. c_rlUnHTTP
  1011. };
  1012. #ifdef UNIX
  1013. const RegEntry c_rlUnHTTPS[] = {
  1014. #else
  1015. const RegList c_rlUnHTTPS = {
  1016. #endif
  1017. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPS, "URL Protocol", REG_SZ, 0, NULL },
  1018. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDefIcon, "", REG_SZ, 0, NULL },
  1019. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeApp, "", REG_SZ, 0, NULL },
  1020. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeTopic, "", REG_SZ, 0, NULL },
  1021. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeexec, "", REG_SZ, 0, NULL },
  1022. { RC_DEL, REF_PRUNE, HKCR, c_szHTTPSOpenCmd, "", REG_SZ, 0, NULL },
  1023. { RC_DEL, REF_EDITFLAGS, HKCR, c_szHTTPS, "", REG_SZ, 0, NULL },
  1024. };
  1025. const RegSet c_rsUnHTTPS = {
  1026. ARRAYSIZE(c_rlUnHTTPS),
  1027. c_rlUnHTTPS
  1028. };
  1029. #ifdef UNIX
  1030. const RegEntry c_rlUnFTP[] = {
  1031. #else
  1032. const RegList c_rlUnFTP = {
  1033. #endif
  1034. { RC_DEL, REF_NORMAL, HKCR, c_szFTP, "URL Protocol", REG_SZ, 0, NULL },
  1035. { RC_DEL, REF_NORMAL, HKCR, c_szFTPDefIcon, "", REG_SZ, 0, NULL },
  1036. { RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeApp, "", REG_SZ, 0, NULL },
  1037. { RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeTopic, "", REG_SZ, 0, NULL },
  1038. { RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeexec, "", REG_SZ, 0, NULL },
  1039. { RC_DEL, REF_PRUNE, HKCR, c_szFTPOpenCmd, "", REG_SZ, 0, NULL },
  1040. { RC_DEL, REF_EDITFLAGS, HKCR, c_szFTP, "", REG_SZ, 0, NULL },
  1041. };
  1042. const RegSet c_rsUnFTP = {
  1043. ARRAYSIZE(c_rlUnFTP),
  1044. c_rlUnFTP
  1045. };
  1046. #ifdef UNIX
  1047. const RegEntry c_rlUnGopher[] = {
  1048. #else
  1049. const RegList c_rlUnGopher = {
  1050. #endif
  1051. { RC_DEL, REF_NORMAL, HKCR, c_szGOPHER, "URL Protocol", REG_SZ, 0, NULL },
  1052. { RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDefIcon, "", REG_SZ, 0, NULL },
  1053. { RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeApp, "", REG_SZ, 0, NULL },
  1054. { RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeTopic, "", REG_SZ, 0, NULL },
  1055. { RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeexec, "", REG_SZ, 0, NULL },
  1056. { RC_DEL, REF_PRUNE, HKCR, c_szGOPHEROpenCmd, "", REG_SZ, 0, NULL },
  1057. { RC_DEL, REF_EDITFLAGS, HKCR, c_szGOPHER, "", REG_SZ, 0, NULL },
  1058. };
  1059. const RegSet c_rsUnGopher = {
  1060. ARRAYSIZE(c_rlUnGopher),
  1061. c_rlUnGopher
  1062. };
  1063. #ifdef UNIX
  1064. const RegEntry c_rlUnHTM[] = {
  1065. #else
  1066. const RegList c_rlUnHTM = {
  1067. #endif
  1068. { RC_DEL, REF_NORMAL, HKCR, c_szHTMDefIcon, "", REG_SZ, 0, NULL },
  1069. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenDdeApp, "", REG_SZ, 0, NULL },
  1070. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenDdeTopic, "", REG_SZ, 0, NULL },
  1071. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenDdeexec, "", REG_SZ, 0, NULL },
  1072. { RC_DEL, REF_PRUNE, HKCR, c_szHTMOpenCmd, "", REG_SZ, 0, NULL },
  1073. { RC_DEL, REF_EDITFLAGS, HKCR, "htmlfile", "", REG_SZ, 0, NULL },
  1074. { RC_DEL, REF_NORMAL, HKCR, c_szMHTMDefIcon, "", REG_SZ, 0, NULL },
  1075. { RC_DEL, REF_EDITFLAGS, HKCR, "mhtmlfile", "", REG_SZ, 0, NULL },
  1076. };
  1077. const RegSet c_rsUnHTM = {
  1078. ARRAYSIZE(c_rlUnHTM),
  1079. c_rlUnHTM
  1080. };
  1081. // Protocol-specific uninstall for full-shell
  1082. #ifdef UNIX
  1083. const RegEntry c_rlUnHTTP_Full[] = {
  1084. #else
  1085. const RegList c_rlUnHTTP_Full = {
  1086. #endif
  1087. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPDdeexec, "NoActivateHandler", REG_SZ, 0, NULL }
  1088. };
  1089. const RegSet c_rsUnHTTP_Full = {
  1090. ARRAYSIZE(c_rlUnHTTP_Full),
  1091. c_rlUnHTTP_Full
  1092. };
  1093. #ifdef UNIX
  1094. const RegEntry c_rlUnHTTPS_Full[] = {
  1095. #else
  1096. const RegList c_rlUnHTTPS_Full = {
  1097. #endif
  1098. { RC_DEL, REF_NORMAL, HKCR, c_szHTTPSDdeexec, "NoActivateHandler", REG_SZ, 0, NULL }
  1099. };
  1100. const RegSet c_rsUnHTTPS_Full = {
  1101. ARRAYSIZE(c_rlUnHTTPS_Full),
  1102. c_rlUnHTTPS_Full
  1103. };
  1104. #ifdef UNIX
  1105. const RegEntry c_rlUnFTP_Full[] = {
  1106. #else
  1107. const RegList c_rlUnFTP_Full = {
  1108. #endif
  1109. { RC_DEL, REF_NORMAL, HKCR, c_szFTPDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
  1110. };
  1111. const RegSet c_rsUnFTP_Full = {
  1112. ARRAYSIZE(c_rlUnFTP_Full),
  1113. c_rlUnFTP_Full
  1114. };
  1115. #ifdef UNIX
  1116. const RegEntry c_rlUnGopher_Full[] = {
  1117. #else
  1118. const RegList c_rlUnGopher_Full = {
  1119. #endif
  1120. { RC_DEL, REF_NORMAL, HKCR, c_szGOPHERDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
  1121. };
  1122. const RegSet c_rsUnGopher_Full = {
  1123. ARRAYSIZE(c_rlUnGopher_Full),
  1124. c_rlUnGopher_Full
  1125. };
  1126. #ifdef UNIX
  1127. const RegEntry c_rlUnHTM_Full[] = {
  1128. #else
  1129. const RegList c_rlUnHTM_Full = {
  1130. // remove the default context menu items
  1131. #endif
  1132. { RC_DEL, REF_NORMAL, HKCR, c_szHTMShell, NULL, REG_SZ, 0, NULL },
  1133. { RC_DEL, REF_NORMAL, HKCR, c_szMHTMShell, NULL, REG_SZ, 0, NULL },
  1134. // remove the default values
  1135. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNew, NULL, REG_SZ, 0, NULL },
  1136. { RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNew, NULL, REG_SZ, 0, NULL },
  1137. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeApp, "", REG_SZ, 0, NULL },
  1138. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeTopic, "", REG_SZ, 0, NULL },
  1139. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
  1140. { RC_DEL, REF_NORMAL, HKCR, c_szHTMOpenNewDdeexec, "", REG_SZ, 0, NULL },
  1141. { RC_DEL, REF_PRUNE, HKCR, c_szHTMOpenNewCmd, "", REG_SZ, 0, NULL },
  1142. { RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeApp, "", REG_SZ, 0, NULL },
  1143. { RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeTopic, "", REG_SZ, 0, NULL },
  1144. { RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "NoActivateHandler", REG_SZ, 0, NULL },
  1145. { RC_DEL, REF_NORMAL, HKCR, c_szMHTMOpenNewDdeexec, "", REG_SZ, 0, NULL },
  1146. { RC_DEL, REF_PRUNE, HKCR, c_szMHTMOpenNewCmd, "", REG_SZ, 0, NULL },
  1147. };
  1148. const RegSet c_rsUnHTM_Full = {
  1149. ARRAYSIZE(c_rlUnHTM_Full),
  1150. c_rlUnHTM_Full
  1151. };
  1152. //
  1153. // Browser-only uninstall
  1154. //
  1155. #ifdef UNIX
  1156. const RegEntry c_rlUninstall_Alone[] = {
  1157. #else
  1158. const RegList c_rlUninstall_Alone = {
  1159. #endif
  1160. { RC_DEL, REF_NORMAL, HKLM, c_szIEOnDesktop, "", REG_SZ, 0, MAKEINTRESOURCE(IDS_REG_THEINTERNET) },
  1161. { RC_DEL, REF_PRUNE, HKCR, c_szIENameSpaceOpen, "", REG_SZ, 0, NULL },
  1162. // InternetShortcut
  1163. { RC_DEL, REF_NORMAL, HKCR, c_szIntShcutOpen, "CLSID", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  1164. { RC_DEL, REF_PRUNE, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
  1165. { RC_DEL, REF_PRUNE, HKCR, c_szIntshcutMayChange, "", REG_SZ, 1, "" },
  1166. { RC_DEL, REF_PRUNE, HKCR, c_szIntShcutPropHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  1167. // Change the inprocserver after removing "MayChangeDefaultMenu" above.
  1168. // Do this so url.dll doesn't repatch the registry.
  1169. { RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "", REG_SZ, sizeof(c_szURL), c_szURL },
  1170. { RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURL), c_szOpenURL },
  1171. { RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnHTTP, HTReg_UninstallProc },
  1172. { RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnHTTPS, HTReg_UninstallProc },
  1173. { RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnFTP, HTReg_UninstallProc },
  1174. { RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnGopher, HTReg_UninstallProc },
  1175. { RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_BROWSERONLY, (LPARAM)&c_rsUnHTM, HTReg_UninstallProc },
  1176. };
  1177. const RegSet c_rsUninstall_Alone = {
  1178. ARRAYSIZE(c_rlUninstall_Alone),
  1179. c_rlUninstall_Alone
  1180. };
  1181. //
  1182. // Full-shell uninstall
  1183. //
  1184. #ifdef UNIX
  1185. const RegEntry c_rlUninstall_Full[] = {
  1186. #else
  1187. const RegList c_rlUninstall_Full = {
  1188. #endif
  1189. // InternetShortcut
  1190. { RC_DEL, REF_NORMAL, HKCR, c_szIntShcutOpen, "CLSID", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  1191. { RC_DEL, REF_NORMAL, HKCR, c_szIntShcutOpen, "LegacyDisable", REG_SZ, 1, ""},
  1192. { RC_DEL, REF_PRUNE, HKCR, c_szIntShcutCMHandler, "", REG_SZ, 1, "" },
  1193. { RC_DEL, REF_PRUNE, HKCR, c_szIntshcutMayChange, "", REG_SZ, 1, "" },
  1194. { RC_DEL, REF_PRUNE, HKCR, c_szIntShcutPropHandler, "", REG_SZ, sizeof(c_szCLSIDIntshcut), c_szCLSIDIntshcut },
  1195. // Change the inprocserver after removing "MayChangeDefaultMenu" above.
  1196. // Do this so url.dll doesn't repatch the registry.
  1197. { RC_ADD, REF_NORMAL, HKCR, c_szIntshcutInproc, "", REG_SZ, sizeof(c_szURL), c_szURL },
  1198. { RC_RUNDLL, REF_NORMAL, HKCR, c_szIntShcutOpenCmd, "", REG_SZ, sizeof(c_szOpenURL), c_szOpenURL },
  1199. // Protocol associations
  1200. { RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTP_Full, HTReg_UninstallProc },
  1201. { RC_CALLBACK, REF_NORMAL, HKCR, "http", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTP, HTReg_UninstallProc },
  1202. { RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTPS_Full, HTReg_UninstallProc },
  1203. { RC_CALLBACK, REF_NORMAL, HKCR, "https", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTTPS, HTReg_UninstallProc },
  1204. { RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnFTP_Full, HTReg_UninstallProc },
  1205. { RC_CALLBACK, REF_NORMAL, HKCR, "ftp", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnFTP, HTReg_UninstallProc },
  1206. { RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnGopher_Full, HTReg_UninstallProc },
  1207. { RC_CALLBACK, REF_NORMAL, HKCR, "gopher", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnGopher, HTReg_UninstallProc },
  1208. { RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTM_Full, HTReg_UninstallProc },
  1209. { RC_CALLBACK, REF_NORMAL, HKCR, "htmlfile", "", PLATFORM_INTEGRATED, (LPARAM)&c_rsUnHTM, HTReg_UninstallProc },
  1210. };
  1211. const RegSet c_rsUninstall_Full = {
  1212. ARRAYSIZE(c_rlUninstall_Full),
  1213. c_rlUninstall_Full
  1214. };
  1215. /*
  1216. * D E F A U L T S E T O F R E G S E T S
  1217. *
  1218. */
  1219. // Common association settings for both browser-only and full-shell
  1220. // This is the required set of entries to make IE be the default
  1221. // browser. Only used if the user hasn't turned this off.
  1222. const RegSet * const g_rgprsDefault[] = {
  1223. &c_rsAssoc,
  1224. &c_rsAssocHTM,
  1225. };
  1226. // Browser-only specific associations
  1227. const RegSet * const g_rgprsDefault_Alone[] = {
  1228. &c_rsAssoc_Alone,
  1229. };
  1230. // Browser-only specific associations for a quick check
  1231. const RegSet * const g_rgprsDefault_Quick[] = {
  1232. &c_rsAssoc_Quick,
  1233. };
  1234. // Full-shell specific associations
  1235. const RegSet * const g_rgprsDefault_Full[] = {
  1236. &c_rsAssoc_Full,
  1237. };
  1238. // This is the set of icon entries that need to be fixed in case of a
  1239. // Win9x to NT5 upgrade.
  1240. const RegSet * const g_rgprsDefault_FixIcon[] = {
  1241. &c_rsAssoc_FixIcon,
  1242. };
  1243. //
  1244. // Other registry settings
  1245. //
  1246. const RegSet * const g_rgprsIE30Only[] =
  1247. {
  1248. &c_rsGeneral_Alone,
  1249. &c_rsAthena,
  1250. };
  1251. const RegSet * const g_rgprsNashOnly[] =
  1252. {
  1253. &c_rsGeneral_Full,
  1254. &c_rsAthena,
  1255. };
  1256. const RegSet * const g_rgprsUninstallIE30[] =
  1257. {
  1258. &c_rsUninstall_Alone,
  1259. };
  1260. const RegSet * const g_rgprsUninstallNash[] =
  1261. {
  1262. &c_rsUninstall_Full,
  1263. };
  1264. /*----------------------------------------------------------
  1265. Purpose: Determine if a particular RegSet is installed
  1266. Returns:
  1267. Cond: --
  1268. */
  1269. BOOL
  1270. IsRegSetInstalled(
  1271. IN const RegSet * prs)
  1272. {
  1273. BOOL bRet = FALSE;
  1274. UINT i;
  1275. HKEY hkey = NULL;
  1276. const RegEntry * pre;
  1277. CHAR szBuffer[1024]; // Registry Data Holder
  1278. CHAR szT[MAX_PATH + 20]; // Need a bit extra for pszIExpAppendage
  1279. DWORD dwType;
  1280. DWORD dwSize;
  1281. DWORD dwSizeExpect;
  1282. DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
  1283. // Check each registry entry. Stop when we encounter the first
  1284. // entry which doesn't match (no need to waste time looking at
  1285. // other entries).
  1286. //
  1287. // In the debug build, we enumerate the whole list, so we can
  1288. // see all the differences at once.
  1289. //
  1290. #ifdef DEBUG
  1291. #define BAIL_OUT bRet = TRUE; continue
  1292. #else
  1293. #define BAIL_OUT goto Bail
  1294. #endif
  1295. for (i = 0; i < prs->cre; i++)
  1296. {
  1297. pre = &(prs->pre[i]);
  1298. // Is this regentry not needed, or can it be set by some third
  1299. // party?
  1300. if (IsFlagSet(pre->dwFlags, REF_NOTNEEDED))
  1301. {
  1302. // Yes; skip to next
  1303. continue;
  1304. }
  1305. // Does the key exist?
  1306. if (NO_ERROR != RegOpenKeyA(pre->hkeyRoot, pre->pszKey, &hkey))
  1307. {
  1308. // No; should it?
  1309. if (RC_DEL == pre->regcmd)
  1310. {
  1311. // No; skip to next
  1312. continue;
  1313. }
  1314. else
  1315. {
  1316. // Yes
  1317. DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s doesn't exist and should", Dbg_RegStr(pre, szDbg)); )
  1318. BAIL_OUT;
  1319. }
  1320. }
  1321. // Yes; should it?
  1322. else if (RC_DEL == pre->regcmd && !*pre->pszValName)
  1323. {
  1324. // No
  1325. DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s exists and shouldn't", Dbg_RegStr(pre, szDbg)); )
  1326. RegCloseKey(hkey);
  1327. BAIL_OUT;
  1328. }
  1329. // Does the value exist?
  1330. dwSize = SIZEOF(szBuffer);
  1331. if (NO_ERROR != RegQueryValueExA(hkey, pre->pszValName, NULL,
  1332. &dwType, (BYTE *)szBuffer, &dwSize))
  1333. {
  1334. // No; should it?
  1335. if (RC_DEL != pre->regcmd)
  1336. {
  1337. // Yes
  1338. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: RegQueryValueEx( %hs, %hs ) Failed", pre->pszKey, pre->pszValName);
  1339. RegCloseKey(hkey);
  1340. BAIL_OUT;
  1341. }
  1342. }
  1343. // Yes; should it?
  1344. else if (RC_DEL == pre->regcmd)
  1345. {
  1346. // No
  1347. ASSERT(pre->pszValName && *pre->pszValName);
  1348. DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s exists and shouldn't",
  1349. Dbg_RegStr(pre, szDbg)); )
  1350. RegCloseKey(hkey);
  1351. BAIL_OUT;
  1352. }
  1353. RegCloseKey(hkey);
  1354. // Is this a value that cannot be stomped (ie, a 3rd party might have
  1355. // set its value, and that's okay with us)?
  1356. if (IsFlagSet(pre->dwFlags, REF_IFEMPTY))
  1357. {
  1358. // Yes; the existence of the value is good enough for us,
  1359. // skip to next
  1360. continue;
  1361. }
  1362. switch (pre->regcmd)
  1363. {
  1364. case RC_ADD:
  1365. case RC_RUNDLL:
  1366. if (dwType == REG_SZ)
  1367. {
  1368. LPCVOID pvValue;
  1369. // Is this a resource string?
  1370. if (0 == HIWORD64(pre->pvValue))
  1371. {
  1372. // Yes; load it
  1373. dwSizeExpect = LoadStringA(g_hinst, PtrToUlong(pre->pvValue), szT, SIZECHARS(szT));
  1374. // Add null and convert to bytes
  1375. dwSizeExpect = CbFromCchA(dwSizeExpect + 1);
  1376. pvValue = szT;
  1377. }
  1378. else
  1379. {
  1380. // No
  1381. ASSERT(pre->pvValue);
  1382. if (RC_RUNDLL == pre->regcmd)
  1383. {
  1384. wnsprintfA(szT, ARRAYSIZE(szT), RUNDLL_CMD_FMT, (LPSTR)pre->pvValue);
  1385. pvValue = szT;
  1386. // Add null and convert to bytes
  1387. dwSizeExpect = CbFromCchA(lstrlenA(szT) + 1);
  1388. }
  1389. else
  1390. {
  1391. pvValue = pre->pvValue;
  1392. if (0 == pre->DUMMYUNION_MEMBER(dwSize))
  1393. dwSizeExpect = (DWORD)CbFromCchA(lstrlenA((LPCSTR)pvValue) + 1);
  1394. else
  1395. dwSizeExpect = (DWORD)pre->DUMMYUNION_MEMBER(dwSize);
  1396. }
  1397. }
  1398. if (dwSize != dwSizeExpect)
  1399. {
  1400. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s string size is %d, expecting %d", Dbg_RegStr(pre, szDbg), dwSize, dwSizeExpect);
  1401. BAIL_OUT;
  1402. }
  1403. // Compare case-insensitive (otherwise we'd just use
  1404. // memcmp below)
  1405. if (0 != StrCmpNIA((LPSTR)pvValue, szBuffer, dwSize / SIZEOF(CHAR)))
  1406. {
  1407. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s string is \"%hs\", expecting \"%hs\"", Dbg_RegStr(pre, szDbg), szBuffer, pvValue);
  1408. BAIL_OUT;
  1409. }
  1410. }
  1411. else
  1412. {
  1413. // Non-string case
  1414. if (dwSize != pre->DUMMYUNION_MEMBER(dwSize))
  1415. {
  1416. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s size is %d, expecting %d", Dbg_RegStr(pre, szDbg), dwSize, pre->DUMMYUNION_MEMBER(dwSize));
  1417. BAIL_OUT;
  1418. }
  1419. if (0 != memcmp(pre->pvValue, (BYTE *)szBuffer, dwSize))
  1420. {
  1421. TraceMsg(TF_REGCHECK, "IsRegSetInstalled: %s value is different, expecting %#08x", Dbg_RegStr(pre, szDbg), *(LPDWORD)pre->pvValue);
  1422. BAIL_OUT;
  1423. }
  1424. }
  1425. break;
  1426. case RC_CALLBACK:
  1427. {
  1428. RSPECPROC pfn = (RSPECPROC)pre->pvValue;
  1429. ASSERT(IS_VALID_CODE_PTR(pfn, RSPECPROC));
  1430. // If the callback returns false, it means we're not the
  1431. // default browser.
  1432. if ( !pfn(RSCB_QUERY, pre, szBuffer, dwSize) )
  1433. BAIL_OUT;
  1434. break;
  1435. }
  1436. case RC_DEL:
  1437. // Work is done before the switch statement. Do nothing here.
  1438. break;
  1439. default:
  1440. ASSERT(0);
  1441. TraceMsg(TF_ERROR, "IsRegSetInstalled: Unhandled Special Type");
  1442. break;
  1443. }
  1444. }
  1445. #ifdef DEBUG
  1446. // In the debug build, leaving the above loop with bRet == TRUE means
  1447. // something doesn't match, so we need to flip the boolean value.
  1448. bRet ^= TRUE;
  1449. #else
  1450. bRet = TRUE;
  1451. Bail:
  1452. #endif
  1453. return bRet;
  1454. }
  1455. /*----------------------------------------------------------
  1456. Purpose: Returns TRUE if the key is empty of all subkeys and
  1457. all (non-default) values.
  1458. If dwFlags has REF_EDITFLAGS set, then this function
  1459. ignores the EditFlags value.
  1460. Returns: see above
  1461. Cond: --
  1462. */
  1463. BOOL
  1464. IsKeyPsuedoEmpty(
  1465. IN HKEY hkey,
  1466. IN LPCSTR pszSubKey,
  1467. IN DWORD dwFlags) // REF_ flags
  1468. {
  1469. BOOL bRet = FALSE;
  1470. DWORD dwRet;
  1471. HKEY hkeyNew;
  1472. dwRet = RegOpenKeyExA(hkey, pszSubKey, 0, KEY_READ, &hkeyNew);
  1473. if (NO_ERROR == dwRet)
  1474. {
  1475. DWORD ckeys;
  1476. DWORD cvalues;
  1477. // Are the any subkeys?
  1478. if (NO_ERROR == RegQueryInfoKey(hkeyNew, NULL, NULL, NULL, &ckeys,
  1479. NULL, NULL, &cvalues, NULL, NULL,
  1480. NULL, NULL) &&
  1481. 0 == ckeys)
  1482. {
  1483. // No; how about non-default values?
  1484. DWORD dwRetDef = SHGetValueA(hkey, pszSubKey, "", NULL, NULL, NULL);
  1485. bRet = (0 == cvalues || (1 == cvalues && NO_ERROR == dwRetDef));
  1486. // Should we ignore edit flags?
  1487. if (!bRet && IsFlagSet(dwFlags, REF_EDITFLAGS))
  1488. {
  1489. // Yes
  1490. DWORD dwRetEdit = SHGetValueA(hkey, pszSubKey, "EditFlags", NULL, NULL, NULL);
  1491. bRet = ((1 == cvalues && NO_ERROR == dwRetEdit) ||
  1492. (2 == cvalues && NO_ERROR == dwRetEdit &&
  1493. NO_ERROR == dwRetDef));
  1494. }
  1495. }
  1496. RegCloseKey(hkeyNew);
  1497. }
  1498. return bRet;
  1499. }
  1500. /*----------------------------------------------------------
  1501. Purpose: Prune the key of our keys and values. Walk back up
  1502. the tree and delete empty keys below us.
  1503. Returns:
  1504. Cond: --
  1505. */
  1506. void
  1507. PruneKey(
  1508. IN HKEY hkeyRoot,
  1509. IN LPCSTR pszKey)
  1510. {
  1511. CHAR szPath[MAX_PATH];
  1512. ASSERT(hkeyRoot);
  1513. ASSERT(pszKey);
  1514. StrCpyNA(szPath, pszKey, ARRAYSIZE(szPath));
  1515. while (PathRemoveFileSpecA(szPath) && *szPath)
  1516. {
  1517. SHDeleteOrphanKeyA(hkeyRoot, szPath);
  1518. }
  1519. }
  1520. /*----------------------------------------------------------
  1521. Purpose: Install a regset (set of registry entries).
  1522. If bDontIntrude is TRUE , then behave such that any
  1523. REF_DONTINTRUDE entry is not forcefully installed (i.e., it
  1524. will only get installed if the key doesn't already
  1525. have a value in it).
  1526. Returns:
  1527. Cond: --
  1528. */
  1529. BOOL
  1530. InstallRegSet(
  1531. IN const RegSet *prs,
  1532. IN BOOL bDontIntrude)
  1533. {
  1534. BOOL bRet = TRUE;
  1535. UINT i;
  1536. HKEY hkey;
  1537. const RegEntry * pre;
  1538. CHAR szBuffer[MAX_PATH + 20]; // Need additional space for pszIExpAppendage
  1539. DWORD dwSize;
  1540. LPCVOID pvValue;
  1541. DEBUG_CODE( TCHAR szDbg[MAX_PATH]; )
  1542. /*
  1543. * Install each registry entry
  1544. */
  1545. for (i = 0; i < prs->cre; i++)
  1546. {
  1547. pre = &(prs->pre[i]);
  1548. // Stomp on this value?
  1549. if (bDontIntrude && IsFlagSet(pre->dwFlags, REF_DONTINTRUDE))
  1550. continue;
  1551. if (IsFlagSet(pre->dwFlags, REF_IFEMPTY))
  1552. {
  1553. // No
  1554. if (NO_ERROR == RegOpenKeyA(pre->hkeyRoot, pre->pszKey, &hkey))
  1555. {
  1556. BOOL bSkip;
  1557. // Are we checking the default value?
  1558. if (0 == *pre->pszValName)
  1559. {
  1560. // Yes; check the size, because default values
  1561. // always exist with at least a null terminator.
  1562. dwSize = 0;
  1563. RegQueryValueExA(hkey, pre->pszValName, NULL, NULL, NULL, &dwSize);
  1564. bSkip = (1 < dwSize);
  1565. }
  1566. else
  1567. {
  1568. // No
  1569. bSkip = (NO_ERROR == RegQueryValueExA(hkey, pre->pszValName,
  1570. NULL, NULL, NULL, NULL));
  1571. }
  1572. RegCloseKey(hkey);
  1573. // Does it exist?
  1574. if (bSkip)
  1575. {
  1576. // Yes; skip it
  1577. DEBUG_CODE( TraceMsg(TF_REGCHECK, "%s already exists, skipping",
  1578. Dbg_RegStr(pre, szDbg)); )
  1579. continue;
  1580. }
  1581. }
  1582. }
  1583. switch (pre->regcmd)
  1584. {
  1585. case RC_ADD:
  1586. case RC_RUNDLL:
  1587. if (NO_ERROR != RegCreateKeyA(pre->hkeyRoot, pre->pszKey, &hkey))
  1588. {
  1589. TraceMsg(TF_ERROR, "InstallRegSet(): RegCreateKey(%hs) Failed", pre->pszKey);
  1590. bRet = FALSE;
  1591. }
  1592. else
  1593. {
  1594. // Is the value a resource string?
  1595. if (REG_SZ == pre->dwType && 0 == HIWORD64(pre->pvValue))
  1596. {
  1597. UINT idRes = PtrToUlong(pre->pvValue);
  1598. // Yes; load it
  1599. dwSize = LoadStringA(g_hinst, idRes, szBuffer, SIZECHARS(szBuffer));
  1600. // Add null and convert to bytes
  1601. dwSize = CbFromCchA(dwSize + 1);
  1602. pvValue = szBuffer;
  1603. }
  1604. else
  1605. {
  1606. // No
  1607. if (RC_RUNDLL == pre->regcmd)
  1608. {
  1609. ASSERT(pre->pvValue);
  1610. ASSERT(REG_SZ == pre->dwType);
  1611. wnsprintfA(szBuffer, ARRAYSIZE(szBuffer), RUNDLL_CMD_FMT, (LPSTR)pre->pvValue);
  1612. pvValue = szBuffer;
  1613. dwSize = CbFromCchA(lstrlenA(szBuffer) + 1);
  1614. }
  1615. else
  1616. {
  1617. // Normal case
  1618. pvValue = pre->pvValue;
  1619. if (0 == pre->DUMMYUNION_MEMBER(dwSize) && REG_SZ == pre->dwType)
  1620. dwSize = CbFromCchA(lstrlenA((LPCSTR)pvValue) + 1);
  1621. else
  1622. dwSize = pre->DUMMYUNION_MEMBER(dwSize);
  1623. }
  1624. }
  1625. ASSERT(0 < dwSize);
  1626. if (NO_ERROR != RegSetValueExA(hkey, pre->pszValName, 0, pre->dwType, (BYTE*)pvValue, dwSize))
  1627. {
  1628. TraceMsg(TF_ERROR, "InstallRegSet(): RegSetValueEx(%hs) Failed", pre->pszValName );
  1629. bRet = FALSE;
  1630. }
  1631. else
  1632. {
  1633. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Setting %s", Dbg_RegStr(pre, szDbg)); )
  1634. }
  1635. RegCloseKey(hkey);
  1636. }
  1637. break;
  1638. case RC_CALLBACK:
  1639. {
  1640. RSPECPROC pfn = (RSPECPROC)pre->pvValue;
  1641. ASSERT(IS_VALID_CODE_PTR(pfn, RSPECPROC));
  1642. pfn(RSCB_INSTALL, pre, NULL, 0);
  1643. break;
  1644. }
  1645. case RC_DEL:
  1646. // Delete the default value, a named value, or the key?
  1647. if (pre->pszValName == NULL)
  1648. {
  1649. // Default value
  1650. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting default value %s", Dbg_RegStr(pre, szDbg)); )
  1651. SHDeleteValueA(pre->hkeyRoot, pre->pszKey, pre->pszValName);
  1652. }
  1653. else if (*pre->pszValName)
  1654. {
  1655. // Named value
  1656. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting value %s", Dbg_RegStr(pre, szDbg)); )
  1657. SHDeleteValueA(pre->hkeyRoot, pre->pszKey, pre->pszValName);
  1658. }
  1659. else
  1660. {
  1661. // Key
  1662. if (IsFlagSet(pre->dwFlags, REF_NUKE))
  1663. {
  1664. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting key %s", Dbg_RegStr(pre, szDbg)); )
  1665. SHDeleteKeyA(pre->hkeyRoot, pre->pszKey);
  1666. }
  1667. // If there are keys or values (other than the
  1668. // default value) that are set, then we don't want
  1669. // to delete either the default value or the
  1670. // key.
  1671. else if (IsKeyPsuedoEmpty(pre->hkeyRoot, pre->pszKey, pre->dwFlags))
  1672. {
  1673. // Delete the default value so SHDeleteOrphanKey
  1674. // will work
  1675. SHDeleteValueA(pre->hkeyRoot, pre->pszKey, "");
  1676. // Delete the EditFlags value? (Without the EditFlags,
  1677. // the user will not be able to specify associations
  1678. // for this class in the FileTypes dialog, b/c that
  1679. // dialog requires this value. So the rule is, this
  1680. // function will delete the EditFlags if there is
  1681. // nothing else in the key.)
  1682. if (IsFlagSet(pre->dwFlags, REF_EDITFLAGS))
  1683. {
  1684. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting %s\\EditFlags", Dbg_RegStr(pre, szDbg)); )
  1685. SHDeleteValueA(pre->hkeyRoot, pre->pszKey, "EditFlags");
  1686. }
  1687. DEBUG_CODE( TraceMsg(TF_REGCHECK, "Deleting empty key %s", Dbg_RegStr(pre, szDbg)); )
  1688. SHDeleteOrphanKeyA(pre->hkeyRoot, pre->pszKey);
  1689. // Should we prune? (This mean we'll walk back up
  1690. // the tree and try deleting empty keys that lead
  1691. // to this key.)
  1692. if (IsFlagSet(pre->dwFlags, REF_PRUNE))
  1693. PruneKey(pre->hkeyRoot, pre->pszKey);
  1694. }
  1695. }
  1696. break;
  1697. default:
  1698. ASSERT(0);
  1699. TraceMsg(TF_ERROR, "InstallRegSet(): Unhandled Special Case");
  1700. break;
  1701. }
  1702. }
  1703. return bRet;
  1704. }
  1705. /****************************************************************************
  1706. FUNCTION: CenterWindow (HWND, HWND)
  1707. PURPOSE: Center one window over another
  1708. COMMENTS:
  1709. Dialog boxes take on the screen position that they were designed at,
  1710. which is not always appropriate. Centering the dialog over a particular
  1711. window usually results in a better position.
  1712. ****************************************************************************/
  1713. BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
  1714. {
  1715. RECT rChild, rParent;
  1716. int wChild, hChild, wParent, hParent;
  1717. int wScreen, hScreen, xNew, yNew;
  1718. HDC hdc;
  1719. // Get the Height and Width of the child window
  1720. GetWindowRect (hwndChild, &rChild);
  1721. wChild = rChild.right - rChild.left;
  1722. hChild = rChild.bottom - rChild.top;
  1723. // Get the Height and Width of the parent window
  1724. GetWindowRect (hwndParent, &rParent);
  1725. wParent = rParent.right - rParent.left;
  1726. hParent = rParent.bottom - rParent.top;
  1727. // Get the display limits
  1728. hdc = GetDC (hwndChild);
  1729. if (hdc)
  1730. {
  1731. wScreen = GetDeviceCaps (hdc, HORZRES);
  1732. hScreen = GetDeviceCaps (hdc, VERTRES);
  1733. ReleaseDC (hwndChild, hdc);
  1734. }
  1735. else
  1736. {
  1737. wScreen = 0;
  1738. hScreen = 0;
  1739. }
  1740. // Calculate new X position, then adjust for screen
  1741. xNew = rParent.left + ((wParent - wChild) /2);
  1742. if (xNew < 0) {
  1743. xNew = 0;
  1744. } else if ((xNew+wChild) > wScreen) {
  1745. xNew = wScreen - wChild;
  1746. }
  1747. // Calculate new Y position, then adjust for screen
  1748. yNew = rParent.top + ((hParent - hChild) /2);
  1749. if (yNew < 0) {
  1750. yNew = 0;
  1751. } else if ((yNew+hChild) > hScreen) {
  1752. yNew = hScreen - hChild;
  1753. }
  1754. // Set it, and return
  1755. return SetWindowPos (hwndChild, NULL,
  1756. xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  1757. }
  1758. /*----------------------------------------------------------
  1759. Purpose: Dialog proc
  1760. */
  1761. BOOL_PTR
  1762. CALLBACK
  1763. AssociationDialogProc(HWND hdlg, UINT uMsg, WPARAM wparam, LPARAM lparam)
  1764. {
  1765. BOOL bMsgHandled = FALSE;
  1766. /* uMsg may be any value. */
  1767. /* wparam may be any value. */
  1768. /* lparam may be any value. */
  1769. switch (uMsg){
  1770. case WM_INITDIALOG:
  1771. CenterWindow( hdlg, GetDesktopWindow());
  1772. if (g_bRunOnNT5)
  1773. {
  1774. // Initialize Checkbox
  1775. // uncheck by default for the first time we show this dialog,
  1776. // user's action is required. we still persist user's last choice.
  1777. if (FALSE == SHRegGetBoolUSValue(REGSTR_PATH_MAIN, TEXT("ShowedCheckBrowser"),
  1778. FALSE, FALSE))
  1779. {
  1780. Button_SetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK), FALSE);
  1781. // mark we have showed this dialog once.
  1782. LPTSTR sz = TEXT("Yes");
  1783. SHRegSetUSValue(REGSTR_PATH_MAIN, TEXT("ShowedCheckBrowser"), REG_SZ,
  1784. (LPBYTE)sz, CbFromCch(lstrlen(sz)+1), SHREGSET_HKCU | SHREGSET_FORCE_HKCU);
  1785. }
  1786. else
  1787. {
  1788. Button_SetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK), IsCheckAssociationsOn());
  1789. }
  1790. }
  1791. else
  1792. Button_SetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK), IsCheckAssociationsOn());
  1793. bMsgHandled = TRUE;
  1794. break;
  1795. //
  1796. // MSN mucks with the registry in a way that causes IE to ask if it's the
  1797. // default browser. Then after they launch IE they maximize the active
  1798. // window. Since the default browsre dialog is active, it gets maximized.
  1799. // Handeling the WM_GETMINMAXINFO prevents this dialog from maximizing.
  1800. //
  1801. case WM_GETMINMAXINFO:
  1802. {
  1803. LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam;
  1804. if (lpmmi)
  1805. {
  1806. RECT rc;
  1807. if (GetWindowRect(hdlg, &rc))
  1808. {
  1809. lpmmi->ptMaxSize.x = rc.right - rc.left;
  1810. lpmmi->ptMaxSize.y = rc.bottom - rc.top;
  1811. lpmmi->ptMaxPosition.x = rc.left;
  1812. lpmmi->ptMaxPosition.y = rc.top;
  1813. bMsgHandled = TRUE;
  1814. }
  1815. }
  1816. }
  1817. break;
  1818. case WM_COMMAND:
  1819. switch (LOWORD(wparam)) {
  1820. case IDYES:
  1821. case IDNO:
  1822. SetCheckAssociations( Button_GetCheck(GetDlgItem(hdlg, IDC_ASSOC_CHECK)) );
  1823. EndDialog( hdlg, LOWORD(wparam));
  1824. break;
  1825. }
  1826. default:
  1827. break;
  1828. }
  1829. return(bMsgHandled);
  1830. }
  1831. /*----------------------------------------------------------
  1832. Purpose: Asks the user whether to make IE be the default browser
  1833. */
  1834. BOOL
  1835. AskUserShouldFixReg()
  1836. {
  1837. return IDYES == SHFusionDialogBoxParam(MLGetHinst(),
  1838. MAKEINTRESOURCE(IDD_ASSOC),
  1839. NULL,
  1840. AssociationDialogProc,
  1841. NULL);
  1842. }
  1843. HRESULT InstallFTPAssociations(void)
  1844. {
  1845. IFtpInstaller * pfi;
  1846. HRESULT hr = CoCreateInstance(CLSID_FtpInstaller, NULL, CLSCTX_INPROC_SERVER, IID_IFtpInstaller, (void **) &pfi);
  1847. if (SUCCEEDED(hr))
  1848. {
  1849. hr = pfi->MakeIEDefautlFTPClient();
  1850. pfi->Release();
  1851. }
  1852. else
  1853. {
  1854. // This may fail to create if FTP wasn't installed, which is
  1855. // a valid install case.
  1856. hr = S_OK;
  1857. }
  1858. return hr;
  1859. }
  1860. /*----------------------------------------------------------
  1861. Purpose: Install file and protocol association settings in
  1862. registry.
  1863. */
  1864. HRESULT
  1865. InstallRegAssoc(
  1866. UINT nInstall, // One of PLATFORM_*
  1867. BOOL bDontIntrude) // TRUE: be non-intrusive
  1868. {
  1869. int i;
  1870. // Install associations common across both IE and Nashville
  1871. for (i = 0; i < ARRAYSIZE(g_rgprsDefault); i++)
  1872. InstallRegSet(g_rgprsDefault[i], bDontIntrude);
  1873. if (PLATFORM_UNKNOWN == nInstall)
  1874. {
  1875. nInstall = WhichPlatform();
  1876. }
  1877. switch (nInstall)
  1878. {
  1879. case PLATFORM_BROWSERONLY:
  1880. for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Alone); i++)
  1881. InstallRegSet(g_rgprsDefault_Alone[i], bDontIntrude);
  1882. break;
  1883. case PLATFORM_INTEGRATED:
  1884. for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Full); i++)
  1885. InstallRegSet(g_rgprsDefault_Full[i], bDontIntrude);
  1886. break;
  1887. default:
  1888. ASSERT(0);
  1889. break;
  1890. }
  1891. InstallFTPAssociations();
  1892. // Notify shell that the associations have changed.
  1893. SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
  1894. return NOERROR;
  1895. }
  1896. /*----------------------------------------------------------
  1897. Purpose: Settings that can only be set after user confirmation.
  1898. */
  1899. void
  1900. InstallAfterConfirmation(
  1901. BOOL bDontIntrude) // TRUE: be non-intrusive
  1902. {
  1903. // on XP, add IE to show up in the start menu as the Internet app
  1904. if (IsOS(OS_WHISTLERORGREATER))
  1905. {
  1906. // Try to set ourselves as the system default Start Menu web browser
  1907. if (InstallRegSet(&c_rsStartMenu_XP, bDontIntrude))
  1908. {
  1909. // If that succeeds, then clear the per-user setting and let
  1910. // the user float with the system default. This is necessary
  1911. // to allow downlevel browsers like Netscape to come in and
  1912. // take over the default browser and steal the user away from us.
  1913. // (We're so nice and accomodating. I bet they won't extend
  1914. // us the same courtesy!)
  1915. SHDeleteValue(HKEY_CURRENT_USER, TEXT("Software\\Clients\\StartMenuInternet"), NULL);
  1916. }
  1917. else
  1918. {
  1919. // We don't have permission to set the global browser, so set ourselves
  1920. // as the browser for this user.
  1921. InstallRegSet(&c_rsStartMenu_XP_CU, bDontIntrude);
  1922. }
  1923. SHSendMessageBroadcast(WM_SETTINGCHANGE, 0, (LPARAM)TEXT("Software\\Clients\\StartMenuInternet"));
  1924. }
  1925. }
  1926. /*----------------------------------------------------------
  1927. Purpose: Set the CheckAssocation setting in the registry
  1928. */
  1929. void
  1930. SetCheckAssociations(
  1931. BOOL fCheck)
  1932. {
  1933. HKEY hk;
  1934. if (RegOpenKeyExA(HKEY_CURRENT_USER, c_szCheckAssnSwitch, 0, KEY_WRITE, &hk) == ERROR_SUCCESS) {
  1935. LPTSTR szStr;
  1936. DWORD dwSize;
  1937. if (fCheck)
  1938. szStr = TEXT("Yes");
  1939. else
  1940. szStr = TEXT("No");
  1941. dwSize = CbFromCch( lstrlen( szStr ) + 1 );
  1942. RegSetValueEx( hk, TEXT("Check_Associations"), 0, REG_SZ, (LPBYTE) szStr, dwSize );
  1943. RegCloseKey( hk );
  1944. }
  1945. }
  1946. /*----------------------------------------------------------
  1947. Purpose: Determines if the user has turned off the "check for
  1948. default browser" in the registry.
  1949. */
  1950. BOOL IsCheckAssociationsOn()
  1951. {
  1952. BOOL rval = TRUE;
  1953. CHAR szBuf[20];
  1954. DWORD dwSize = sizeof(szBuf);
  1955. DWORD dwValType;
  1956. if (NO_ERROR == SHGetValueA(HKEY_CURRENT_USER, c_szCheckAssnSwitch,
  1957. "Check_Associations", &dwValType,
  1958. szBuf, &dwSize))
  1959. {
  1960. if ((dwValType == REG_SZ) && (dwSize < sizeof(szBuf))) {
  1961. if (StrCmpIA( szBuf, "No") == 0)
  1962. rval = FALSE;
  1963. }
  1964. }
  1965. return( rval );
  1966. }
  1967. /***********************************************************************
  1968. These routines are used to repair damage done to Internet Explorer's
  1969. settings by "Netscape Navigator" and "Netscape TuneUp For IE"
  1970. ***********************************************************************/
  1971. //
  1972. // Prototype for advpack functions
  1973. //
  1974. HRESULT RunSetupCommand(HWND hWnd, LPCSTR szCmdName, LPCSTR szInfSection, LPCSTR szDir, LPCSTR lpszTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved);
  1975. //
  1976. // This flag tells us whether it's ok to used the
  1977. // cached BOOL for IsResetWebSettingsRequired.
  1978. //
  1979. BOOL g_fAlreadyCheckedForClobber = FALSE;
  1980. HRESULT RunSetupCommandW(HWND hWnd, LPCWSTR szCmdName, LPCWSTR szInfSection, LPCWSTR szDir, LPCWSTR lpszTitle, HANDLE *phEXE, DWORD dwFlags, LPVOID pvReserved)
  1981. {
  1982. CHAR szCmdNameA[MAX_PATH];
  1983. CHAR szInfSectionA[MAX_PATH];
  1984. CHAR szDirA[MAX_PATH];
  1985. SHUnicodeToAnsi(szCmdName,szCmdNameA,ARRAYSIZE(szCmdNameA));
  1986. SHUnicodeToAnsi(szInfSection,szInfSectionA,ARRAYSIZE(szInfSectionA));
  1987. SHUnicodeToAnsi(szDir,szDirA,ARRAYSIZE(szDirA));
  1988. ASSERT(NULL == pvReserved);
  1989. ASSERT(NULL == lpszTitle);
  1990. return RunSetupCommand(hWnd, szCmdNameA, szInfSectionA, szDirA, NULL, phEXE, dwFlags, NULL);
  1991. }
  1992. //
  1993. // Path to the inf file
  1994. //
  1995. #define IERESTORE_FILENAME TEXT("iereset.inf")
  1996. #define INF_PATH TEXT("inf")
  1997. //
  1998. // Names of the sections in our inf file
  1999. //
  2000. #define INFSECTION_HOMEPAGE TEXT("RestoreHomePage")
  2001. #define INFSECTION_SETTINGS TEXT("RestoreBrowserSettings")
  2002. #define IE_VERIFY_REGKEY TEXT("Software\\Microsoft\\Internet Explorer\\Main")
  2003. #define IE_VERIFY_REGVALUE TEXT("Default_Page_URL")
  2004. #define INFSECTION_VERIFY TEXT("Strings")
  2005. #define IE_VERIFY_INFKEY TEXT("START_PAGE_URL")
  2006. void GetIEResetInfFileName(LPWSTR pszBuffer)
  2007. {
  2008. TCHAR szWindowsDir[MAX_PATH];
  2009. if (NULL == pszBuffer)
  2010. return;
  2011. GetWindowsDirectory(szWindowsDir,ARRAYSIZE(szWindowsDir));
  2012. wnsprintfW(
  2013. pszBuffer,
  2014. MAX_PATH,
  2015. TEXT("%s\\%s\\%s"),
  2016. szWindowsDir,INF_PATH,IERESTORE_FILENAME);
  2017. return;
  2018. }
  2019. /*
  2020. * CheckIESettings
  2021. *
  2022. * This function will try to determine whether or not IE's settings
  2023. * have been clobbered by another browser.
  2024. *
  2025. * Returns S_OK if IE settings are intact.
  2026. * Returns S_FALSE if someone has mucked with the IE settings
  2027. * Returns E_FAIL on error
  2028. *
  2029. */
  2030. HRESULT CheckWebSettings(void)
  2031. {
  2032. TCHAR szInfPath[MAX_PATH];
  2033. TCHAR szDataFromInf[MAX_PATH];
  2034. TCHAR szDataFromReg[MAX_PATH];
  2035. LONG retval;
  2036. HKEY hkey;
  2037. DWORD dwType;
  2038. DWORD dwSize = sizeof(szDataFromReg);
  2039. //
  2040. // Get the path to the inf file
  2041. //
  2042. GetIEResetInfFileName(szInfPath);
  2043. //
  2044. // Read the string from the inf file
  2045. //
  2046. retval = SHGetIniString(
  2047. INFSECTION_VERIFY,
  2048. IE_VERIFY_INFKEY,
  2049. szDataFromInf,
  2050. ARRAYSIZE(szDataFromInf),
  2051. szInfPath);
  2052. if (retval <= 0)
  2053. return E_FAIL;
  2054. //
  2055. // Open the corresponding key in the registry
  2056. //
  2057. retval = RegOpenKeyEx(
  2058. HKEY_LOCAL_MACHINE,
  2059. IE_VERIFY_REGKEY,
  2060. NULL,
  2061. KEY_READ,
  2062. &hkey);
  2063. if (retval != ERROR_SUCCESS)
  2064. return E_FAIL;
  2065. //
  2066. // Read the data from the registry
  2067. //
  2068. retval = RegQueryValueEx(
  2069. hkey,
  2070. IE_VERIFY_REGVALUE,
  2071. NULL,
  2072. &dwType,
  2073. (LPBYTE)szDataFromReg,
  2074. &dwSize);
  2075. if (retval != ERROR_SUCCESS)
  2076. {
  2077. RegCloseKey(hkey);
  2078. return E_FAIL;
  2079. }
  2080. ASSERT(dwType == REG_SZ);
  2081. RegCloseKey(hkey);
  2082. //
  2083. // Return S_OK if they match, S_FALSE if they don't
  2084. //
  2085. return StrCmp(szDataFromReg,szDataFromInf) ? S_FALSE : S_OK;
  2086. }
  2087. extern "C" BOOL IsResetWebSettingsRequired(void)
  2088. {
  2089. static BOOL fRequired;
  2090. if (!g_fAlreadyCheckedForClobber)
  2091. {
  2092. fRequired = (S_FALSE == CheckWebSettings());
  2093. g_fAlreadyCheckedForClobber = TRUE;
  2094. }
  2095. return fRequired;
  2096. }
  2097. HRESULT ResetWebSettingsHelper(BOOL fRestoreHomePage)
  2098. {
  2099. HRESULT hr;
  2100. TCHAR szTempPath[MAX_PATH];
  2101. TCHAR szInfPath[MAX_PATH];
  2102. GetTempPath(ARRAYSIZE(szTempPath),szTempPath);
  2103. GetIEResetInfFileName(szInfPath);
  2104. g_fAlreadyCheckedForClobber = FALSE;
  2105. //
  2106. // Run the main part of the inf file
  2107. //
  2108. hr = RunSetupCommandW(
  2109. NULL,
  2110. szInfPath,
  2111. INFSECTION_SETTINGS,
  2112. szTempPath,
  2113. NULL,
  2114. NULL,
  2115. RSC_FLAG_INF|RSC_FLAG_QUIET,
  2116. NULL);
  2117. //
  2118. // Also, reset their homepage if requested to do so
  2119. //
  2120. if (SUCCEEDED(hr) && fRestoreHomePage)
  2121. hr = RunSetupCommandW(
  2122. NULL,
  2123. szInfPath,
  2124. INFSECTION_HOMEPAGE,
  2125. szTempPath,
  2126. NULL,
  2127. NULL,
  2128. RSC_FLAG_INF|RSC_FLAG_QUIET,
  2129. NULL);
  2130. return hr;
  2131. }
  2132. //
  2133. // Dialog Procedure for the "reset web settings" dialog
  2134. //
  2135. // Return values are:
  2136. //
  2137. // -1 Something went wrong
  2138. // 0 The user changes his/her mind
  2139. // 1 We reset everything except the homepage
  2140. // 2 We reset everything including the homepage
  2141. //
  2142. BOOL_PTR CALLBACK ResetWebSettingsDlgProc(HWND hdlg, UINT uMsg, WPARAM wparam, LPARAM lparam)
  2143. {
  2144. switch (uMsg)
  2145. {
  2146. case WM_INITDIALOG:
  2147. CenterWindow(hdlg, GetDesktopWindow());
  2148. CheckDlgButton(hdlg,IDC_RESET_WEB_SETTINGS_HOMEPAGE,BST_CHECKED);
  2149. return TRUE;
  2150. case WM_COMMAND:
  2151. switch(LOWORD(wparam))
  2152. {
  2153. case IDYES:
  2154. {
  2155. HRESULT hr;
  2156. BOOL fResetHomePage = (BST_CHECKED == IsDlgButtonChecked(hdlg,IDC_RESET_WEB_SETTINGS_HOMEPAGE));
  2157. //
  2158. // Restore the settings to their IE defaults
  2159. //
  2160. hr = ResetWebSettingsHelper(fResetHomePage);
  2161. if (!IsIEDefaultBrowser())
  2162. {
  2163. InstallRegAssoc(WhichPlatform(), FALSE);
  2164. InstallAfterConfirmation(FALSE);
  2165. }
  2166. if (FAILED(hr))
  2167. EndDialog(hdlg, -1);
  2168. else if (fResetHomePage)
  2169. EndDialog(hdlg, 2);
  2170. else
  2171. EndDialog(hdlg, 1);
  2172. }
  2173. return TRUE;
  2174. case IDCANCEL:
  2175. case IDNO:
  2176. EndDialog(hdlg, 0);
  2177. return TRUE;
  2178. default:
  2179. return FALSE;
  2180. }
  2181. default:
  2182. return FALSE;
  2183. }
  2184. }
  2185. HRESULT ResetWebSettings(HWND hwnd, BOOL *pfChangedHomePage)
  2186. {
  2187. HRESULT hr;
  2188. if (pfChangedHomePage)
  2189. *pfChangedHomePage = FALSE;
  2190. switch (DialogBoxParam(
  2191. MLGetHinst(),
  2192. MAKEINTRESOURCE(IDD_RESET_WEB_SETTINGS),
  2193. hwnd,
  2194. ResetWebSettingsDlgProc,
  2195. NULL))
  2196. {
  2197. case -1:
  2198. hr = E_FAIL;
  2199. break;
  2200. case 0:
  2201. hr = S_FALSE;
  2202. break;
  2203. case 1:
  2204. hr = S_OK;
  2205. break;
  2206. case 2:
  2207. if (pfChangedHomePage)
  2208. *pfChangedHomePage = TRUE;
  2209. hr = S_OK;
  2210. break;
  2211. default:
  2212. ASSERT(0);
  2213. hr = E_FAIL;
  2214. break;
  2215. }
  2216. if (FAILED(hr))
  2217. {
  2218. MLShellMessageBox(
  2219. hwnd,
  2220. MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_FAILURE),
  2221. MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_TITLE),
  2222. MB_OK | MB_ICONEXCLAMATION);
  2223. }
  2224. else if (hr == S_OK)
  2225. {
  2226. MLShellMessageBox(
  2227. hwnd,
  2228. MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_SUCCESS),
  2229. MAKEINTRESOURCE(IDS_RESET_WEB_SETTINGS_TITLE),
  2230. MB_OK | MB_ICONINFORMATION);
  2231. }
  2232. return hr;
  2233. }
  2234. void EnsureWebViewRegSettings()
  2235. {
  2236. // We do the following mini-check regardless of the user's settings,
  2237. // and for every window we open
  2238. if (!IsRegSetInstalled(&c_rsAssocHTM_WV))
  2239. InstallRegSet(&c_rsAssocHTM_WV, FALSE);
  2240. }
  2241. void FixIcons()
  2242. {
  2243. int i;
  2244. for (i = 0; i < ARRAYSIZE(g_rgprsDefault_FixIcon); i++)
  2245. {
  2246. // 2nd param FALSE ==> always intrude.
  2247. InstallRegSet(g_rgprsDefault_FixIcon[i], FALSE);
  2248. }
  2249. }
  2250. /*----------------------------------------------------------
  2251. Purpose: Function that determines if we are the default browser.
  2252. If not the default browser, this function will
  2253. ask the user to if they want to become the default
  2254. browser and make those changes.
  2255. */
  2256. void
  2257. DetectAndFixAssociations()
  2258. {
  2259. TraceMsg(TF_REGCHECK, "Performing expensive registry query for default browser!");
  2260. // We will become the Default browser if:
  2261. // 1. The User has "Check Associations" On,
  2262. // 2. We don't own the associations, and
  2263. // 3. The user said Yes when we displayed the dialog.
  2264. if (IsCheckAssociationsOn() &&
  2265. !IsIEDefaultBrowser() &&
  2266. AskUserShouldFixReg())
  2267. {
  2268. InstallRegAssoc(WhichPlatform(), FALSE);
  2269. InstallAfterConfirmation(FALSE);
  2270. }
  2271. }
  2272. /*
  2273. A really quick - non - through check to see if IE is likely the
  2274. default browser
  2275. */
  2276. BOOL IsIEDefaultBrowserQuick(void)
  2277. {
  2278. int i;
  2279. BOOL bAssociated = TRUE;
  2280. TraceMsg(TF_REGCHECK, "Performing expensive registry query for default browser!");
  2281. // Check the settings common to all platforms
  2282. for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Quick); i++)
  2283. {
  2284. if (! IsRegSetInstalled(g_rgprsDefault_Quick[i]))
  2285. bAssociated = FALSE;
  2286. }
  2287. return bAssociated;
  2288. }
  2289. /*----------------------------------------------------------
  2290. Purpose: Function that determines if we are the default browser.
  2291. */
  2292. BOOL
  2293. IsIEDefaultBrowser(void)
  2294. {
  2295. int i;
  2296. BOOL bAssociated = TRUE;
  2297. UINT nInstall = WhichPlatform();
  2298. TraceMsg(TF_REGCHECK, "Performing expensive registry query for default browser!");
  2299. // Check the settings common to all platforms
  2300. for (i = 0; i < ARRAYSIZE(g_rgprsDefault); i++)
  2301. {
  2302. if (! IsRegSetInstalled(g_rgprsDefault[i]))
  2303. bAssociated = FALSE;
  2304. }
  2305. if (bAssociated)
  2306. {
  2307. // Check specific to IE or Nashville
  2308. switch (nInstall)
  2309. {
  2310. case PLATFORM_BROWSERONLY:
  2311. for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Alone); i++)
  2312. {
  2313. if (! IsRegSetInstalled(g_rgprsDefault_Alone[i]))
  2314. {
  2315. bAssociated = FALSE;
  2316. break;
  2317. }
  2318. }
  2319. break;
  2320. case PLATFORM_INTEGRATED:
  2321. for (i = 0; i < ARRAYSIZE(g_rgprsDefault_Full); i++)
  2322. {
  2323. if (! IsRegSetInstalled(g_rgprsDefault_Full[i]))
  2324. {
  2325. bAssociated = FALSE;
  2326. break;
  2327. }
  2328. }
  2329. break;
  2330. default:
  2331. ASSERT(0);
  2332. break;
  2333. }
  2334. }
  2335. // If IE is the default browser and this was an NT5Upgrade scenario,
  2336. // fix the Icons references.
  2337. if (g_bNT5Upgrade && bAssociated)
  2338. {
  2339. FixIcons();
  2340. }
  2341. return bAssociated;
  2342. }
  2343. /*----------------------------------------------------------
  2344. Purpose: Checks if we're installing over IE. This function
  2345. looks at the associated shell\open\command handler
  2346. for the http protocol.
  2347. Returns: TRUE if we're installing over IE
  2348. */
  2349. BOOL
  2350. AreWeInstallingOverIE(void)
  2351. {
  2352. BOOL bRet = FALSE;
  2353. CHAR sz[MAX_PATH + 20]; // add some padding for arguments
  2354. DWORD cbData = SIZEOF(sz);
  2355. if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, c_szHTTPOpenCmd, "",
  2356. NULL, sz, &cbData) &&
  2357. StrStrIA(sz, IEXPLORE_EXE) || StrStrIA(sz, EXPLORER_EXE))
  2358. {
  2359. TraceMsg(TF_REGCHECK, "Installing over IEXPLORE.EXE");
  2360. bRet = TRUE;
  2361. }
  2362. return bRet;
  2363. }
  2364. #if 0
  2365. BOOL ShouldIEBeDefaultBrowser(void)
  2366. {
  2367. BOOL bRet = TRUE; // default to TRUE (eg take over the association)
  2368. CHAR sz[MAX_PATH] = "";
  2369. DWORD cchData = ARRAYSIZE(sz);
  2370. if (SUCCEEDED(AssocQueryStringA(0, ASSOCSTR_COMMAND, ".htm", NULL, sz, &cchData)))
  2371. {
  2372. if (sz[0] && !StrStrIA(sz, IEXPLORE_EXE))
  2373. {
  2374. TraceMsg(TF_REGCHECK, "%s is the default browser (NOT iexplore.exe)", sz);
  2375. bRet = FALSE;
  2376. }
  2377. else
  2378. {
  2379. // if sz[0] is NULL, (probably broken reg) - Let IE be the Default Browser.
  2380. // or IE may be the Default browser setting.
  2381. TraceMsg(TF_REGCHECK, "IEXPLORE.EXE is assumed to be the default browser");
  2382. }
  2383. }
  2384. else
  2385. {
  2386. //May be a Broken Registry - Default to IE.
  2387. TraceMsg(TF_REGCHECK, "IEXPLORE.EXE is assumed to be the default browser due to broken Association");
  2388. }
  2389. return bRet;
  2390. }
  2391. #else
  2392. BOOL ShouldIEBeDefaultBrowser(void)
  2393. {
  2394. BOOL bRet = TRUE; // default to TRUE (eg take over the association)
  2395. CHAR sz[MAX_PATH + 20]; // add some padding for arguments
  2396. DWORD cbData = ARRAYSIZE(sz);
  2397. sz[0] = '\0';
  2398. if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, ".htm", "", NULL, sz, &cbData))
  2399. {
  2400. if (!sz[0])
  2401. {
  2402. // null key so return TRUE
  2403. return bRet;
  2404. }
  2405. else if (!StrCmpIA(sz, "htmlfile"))
  2406. {
  2407. // Maybe, make sure further
  2408. sz[0] = '\0';
  2409. cbData = ARRAYSIZE(sz);
  2410. if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, c_szHTMOpenCmd, "",
  2411. NULL, sz, &cbData))
  2412. {
  2413. if (!sz[0] || // if sz[0] is NULL, we will take it over (probably broken reg)
  2414. StrStrIA(sz, IEXPLORE_EXE))
  2415. {
  2416. // Default browser was IE, so we return TRUE
  2417. TraceMsg(TF_REGCHECK, "IEXPLORE.EXE is the default browser");
  2418. }
  2419. else
  2420. {
  2421. TraceMsg(TF_REGCHECK, "%s is the default browser (NOT iexplore.exe)", sz);
  2422. bRet = FALSE;
  2423. }
  2424. }
  2425. }
  2426. else
  2427. {
  2428. // the progid does not point to "htmlfile", so IE cant be the default browser
  2429. TraceMsg(TF_REGCHECK, "%s is the .htm progid (NOT htmlfile)", sz);
  2430. bRet = FALSE;
  2431. }
  2432. }
  2433. // .htm progid key does not exist, so we return TRUE
  2434. return bRet;
  2435. }
  2436. #endif
  2437. #define SZ_REGKEY_FTPSHELLOPEN TEXT("ftp\\shell\\open")
  2438. #define SZ_REGKEY_COMMAND TEXT("command")
  2439. #define SZ_REGKEY_DDEEXEC TEXT("ddeexec\\ifExec")
  2440. #define SZ_IEXPLORE_FTP_NEW TEXT("iexplore.exe\" %1")
  2441. #define SZ_IEXPLORE_FTP_OLD TEXT("iexplore.exe\" -nohome")
  2442. HRESULT UpgradeSettings(void)
  2443. {
  2444. HRESULT hr = S_OK;
  2445. HKEY hKey;
  2446. LONG lRet = RegOpenKey(HKEY_CLASSES_ROOT, SZ_REGKEY_FTPSHELLOPEN, &hKey);
  2447. hr = HRESULT_FROM_WIN32(lRet);
  2448. if (hKey)
  2449. {
  2450. TCHAR szData[MAX_PATH];
  2451. LONG cbSize = sizeof(szData);
  2452. lRet = RegQueryValue(hKey, SZ_REGKEY_COMMAND, szData, &cbSize);
  2453. hr = HRESULT_FROM_WIN32(lRet);
  2454. if (SUCCEEDED(hr))
  2455. {
  2456. DWORD cchStart = (lstrlen(szData) - ARRAYSIZE(SZ_IEXPLORE_FTP_OLD) + 1);
  2457. // Do we own it?
  2458. if (0 == StrCmp(SZ_IEXPLORE_FTP_OLD, &szData[cchStart]))
  2459. {
  2460. // Yes, so we can upgrade it.
  2461. // Buffer Overflow isn't a problem because I know SZ_IEXPLORE_FTP_NEW is smaller
  2462. // than SZ_IEXPLORE_FTP_OLD.
  2463. StrCpyN(&szData[cchStart], SZ_IEXPLORE_FTP_NEW, ARRAYSIZE(szData));
  2464. // Yes, so let's upgrade.
  2465. lRet = RegSetValue(hKey, SZ_REGKEY_COMMAND, REG_SZ, szData, lstrlen(szData));
  2466. hr = HRESULT_FROM_WIN32(lRet);
  2467. if (SUCCEEDED(hr))
  2468. {
  2469. lRet = RegSetValue(hKey, SZ_REGKEY_DDEEXEC, REG_SZ, TEXT(""), ARRAYSIZE(TEXT("")));
  2470. hr = HRESULT_FROM_WIN32(lRet);
  2471. }
  2472. }
  2473. }
  2474. RegCloseKey(hKey);
  2475. }
  2476. return hr;
  2477. }
  2478. /*----------------------------------------------------------
  2479. Purpose: Install registry info based upon which shell we're running
  2480. */
  2481. HRESULT InstallIEAssociations(DWORD dwFlags) // IEA_* flags
  2482. {
  2483. int i;
  2484. UINT nInstall = WhichPlatform();
  2485. BOOL bDontIntrude = TRUE;
  2486. // If IE was the default browser before (or the registry is messed up)
  2487. // or setup is forcing us to register then we want to force IE to be
  2488. // the default browser
  2489. if (ShouldIEBeDefaultBrowser() || IsFlagSet(dwFlags, IEA_FORCEIE))
  2490. bDontIntrude = FALSE;
  2491. // Install file and protocol associations
  2492. InstallRegAssoc(nInstall, bDontIntrude);
  2493. // Install other registry settings
  2494. switch (nInstall)
  2495. {
  2496. case PLATFORM_BROWSERONLY:
  2497. for (i = 0; i < ARRAYSIZE(g_rgprsIE30Only); i++)
  2498. {
  2499. InstallRegSet(g_rgprsIE30Only[i], bDontIntrude);
  2500. }
  2501. break;
  2502. case PLATFORM_INTEGRATED:
  2503. for (i = 0; i < ARRAYSIZE(g_rgprsNashOnly); i++)
  2504. {
  2505. InstallRegSet(g_rgprsNashOnly[i], bDontIntrude);
  2506. }
  2507. break;
  2508. default:
  2509. ASSERT(0);
  2510. break;
  2511. }
  2512. InstallFTPAssociations();
  2513. return NOERROR;
  2514. }
  2515. HRESULT UninstallPlatformRegItems(BOOL bIntegrated)
  2516. {
  2517. int i;
  2518. UINT uPlatform = bIntegrated ? PLATFORM_INTEGRATED : PLATFORM_BROWSERONLY;
  2519. switch (uPlatform)
  2520. {
  2521. case PLATFORM_BROWSERONLY:
  2522. for (i = 0; i < ARRAYSIZE(g_rgprsUninstallIE30); i++)
  2523. {
  2524. InstallRegSet(g_rgprsUninstallIE30[i], FALSE);
  2525. }
  2526. break;
  2527. case PLATFORM_INTEGRATED:
  2528. for (i = 0; i < ARRAYSIZE(g_rgprsUninstallNash); i++)
  2529. {
  2530. InstallRegSet(g_rgprsUninstallNash[i], FALSE);
  2531. }
  2532. break;
  2533. default:
  2534. // Don't do anything
  2535. break;
  2536. }
  2537. return NOERROR;
  2538. }
  2539. void UninstallCurrentPlatformRegItems()
  2540. {
  2541. CHAR sz[MAX_PATH + 20]; // add some padding for arguments
  2542. DWORD cbData = SIZEOF(sz);
  2543. if (NO_ERROR == SHGetValueA(HKEY_CLASSES_ROOT, c_szHTMOpenNewCmd, "",
  2544. NULL, sz, &cbData))
  2545. {
  2546. // Remove IE4 shell integrated settings
  2547. UninstallPlatformRegItems(TRUE);
  2548. }
  2549. else if (AreWeInstallingOverIE())
  2550. {
  2551. // Remove IE3 / browser only settings
  2552. UninstallPlatformRegItems(FALSE);
  2553. }
  2554. }