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

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