Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

443 lines
12 KiB

  1. #include "priv.h"
  2. #include <iethread.h>
  3. #include "winlist.h"
  4. #include "htregmng.h"
  5. #include "resource.h"
  6. #include "inetnot.h"
  7. #include <mluisupp.h>
  8. // Inststub uses kernel string funcions and unbounded buffer functions
  9. #undef lstrcpyn
  10. #undef lstrcmp
  11. #undef lstrcpy
  12. #undef lstrcmpi
  13. #undef StrCpyW
  14. #define lstrcpy StrCpyW
  15. #define lstrcpyn StrCpyNW
  16. #define lstrcmp StrCmpW
  17. #define lstrcmpi StrCmpIW
  18. // need these defined before including <runonce.c> which is included by <inststub.h>
  19. BOOL g_fCleanBoot = FALSE;
  20. BOOL g_fEndSession = FALSE;
  21. #include <inststub.h>
  22. #undef lstrcpyn
  23. #undef lstrcmp
  24. #undef lstrcpy
  25. #undef lstrcmpi
  26. #define lstrcpyn Do_not_use_lstrcpyn_use_StrCpyN
  27. #define lstrcmp Do_not_use_lstrcmp_use_StrCmp
  28. #define lstrcpy Do_not_use_lstrcpy_use_StrCpyN
  29. #define lstrcmpi Do_not_use_lstrcmpi_use_StrCmpI
  30. #define StrCpyW Do_not_use_StrCpyW_use_StrCpyNW
  31. #ifdef UNIX
  32. #include "unixstuff.h"
  33. #endif
  34. /* Old install stub API (no parameters) for compatibility for a few builds */
  35. EXTERN_C void RunInstallUninstallStubs(void)
  36. {
  37. RunInstallUninstallStubs2(NULL);
  38. }
  39. void IERevokeClassFactoryObject(void);
  40. #ifndef POSTPOSTSPLIT
  41. // This value will be initialized to 0 only when we are under IExplorer.exe
  42. UINT g_tidParking = 0;
  43. #endif
  44. #define DM_FAVORITES 0
  45. #ifdef BETA_WARNING
  46. #pragma message("buidling with time bomb enabled")
  47. void DoTimebomb(HWND hwnd)
  48. {
  49. SYSTEMTIME st;
  50. GetSystemTime(&st);
  51. //
  52. // Revision History:
  53. // End of October, 1996
  54. // April, 1997
  55. // September, 1997 (for beta-1)
  56. // November 15th, 1997 (for beta-2)
  57. //
  58. if (st.wYear > 1997 || (st.wYear==1997 && st.wMonth > 11) ||
  59. (st.wYear==1997 && st.wMonth == 11 && st.wDay > 15))
  60. {
  61. TCHAR szTitle[128];
  62. TCHAR szBeta[512];
  63. MLLoadShellLangString(IDS_CABINET, szTitle, ARRAYSIZE(szTitle));
  64. MLLoadShellLangString(IDS_BETAEXPIRED, szBeta, ARRAYSIZE(szBeta));
  65. MessageBox(hwnd, szBeta, szTitle, MB_OK);
  66. }
  67. }
  68. #else
  69. #define DoTimebomb(hwnd)
  70. #endif
  71. /*----------------------------------------------------------
  72. Purpose: Initialize the favorites folder if it doesn't exist.
  73. Returns: --
  74. Cond: As a side-effect, SHGetSpecialFolderPath calls Ole
  75. functions. So this function must be called after
  76. OleInitialize has been called.
  77. Note: This is only really required on win95 / NT4 in
  78. browser only mode. The shell32.dll that ships
  79. with IE4 can handle CSIDL_FAVORITES with fCreate=TRUE.
  80. */
  81. void InitFavoritesDir()
  82. {
  83. TCHAR szPath[MAX_PATH];
  84. if (!SHGetSpecialFolderPath(NULL, szPath, CSIDL_FAVORITES, TRUE))
  85. {
  86. TCHAR szFavorites[80];
  87. TraceMsg(DM_FAVORITES, "InitFavoritesDir -- no favorites");
  88. // if this failed, that means we need to create it ourselves
  89. GetWindowsDirectory(szPath, ARRAYSIZE(szPath));
  90. MLLoadString(IDS_FAVORITES, szFavorites, ARRAYSIZE(szFavorites));
  91. PathCombine(szPath, szPath, szFavorites);
  92. SHCreateDirectory(NULL, szPath);
  93. HKEY hkExplorer;
  94. if (RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_EXPLORER, &hkExplorer) == ERROR_SUCCESS)
  95. {
  96. HKEY hkUSF;
  97. if (RegCreateKey(hkExplorer, TEXT("User Shell Folders"), &hkUSF) == ERROR_SUCCESS)
  98. {
  99. BOOL f;
  100. TraceMsg(DM_FAVORITES, "InitFavoritesDir -- created in %s", szPath);
  101. RegSetValueEx(hkUSF, TEXT("Favorites"), 0, REG_SZ, (LPBYTE)szPath, (1 + lstrlen(szPath)) * SIZEOF(TCHAR));
  102. f = SHGetSpecialFolderPath(NULL, szPath, CSIDL_FAVORITES, TRUE);
  103. TraceMsg(DM_FAVORITES, "InitFavoritesDir -- cached at %d %s", f, szPath);
  104. ASSERT(f);
  105. RegCloseKey(hkUSF);
  106. }
  107. RegCloseKey(hkExplorer);
  108. }
  109. }
  110. }
  111. #ifdef ENABLE_CHANNELS
  112. //
  113. // Copy ChanBarSetAutoLaunchRegValue from browseui.
  114. //
  115. //extern void ChanBarSetAutoLaunchRegValue(BOOL fAutoLaunch);
  116. void ChanBarSetAutoLaunchRegValue(BOOL fAutoLaunch)
  117. {
  118. SHRegSetUSValue(TEXT("Software\\Microsoft\\Internet Explorer\\Main"),
  119. TEXT("Show_ChannelBand"), REG_SZ,
  120. fAutoLaunch ? TEXT("yes") : TEXT("no"),
  121. sizeof(fAutoLaunch ? TEXT("yes") : TEXT("no")),
  122. SHREGSET_HKCU | SHREGSET_FORCE_HKCU);
  123. }
  124. #endif // ENABLE_CHANNELS
  125. STDAPI SHCreateSplashScreen(ISplashScreen ** pSplash);
  126. typedef BOOL (*PFNISDEBUGGERPRESENT)(void);
  127. void CUrlHistory_CleanUp();
  128. //
  129. // Mean Time To Failure check routines
  130. //
  131. #define REG_STR_IE TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\Main")
  132. #define REG_STR_CLEAN TEXT("CleanBrowserShutdown")
  133. LONG GetSessionCount();
  134. void WriteCleanBrowserShutdown(BOOL fClean)
  135. {
  136. HKEY hkey;
  137. DWORD dwValue = (DWORD)fClean;
  138. //
  139. // Only do MTTF on the first browser session
  140. //
  141. if (GetSessionCount() != 0)
  142. return;
  143. if (RegOpenKeyEx(HKEY_CURRENT_USER, REG_STR_IE, 0, KEY_WRITE, &hkey)
  144. == ERROR_SUCCESS)
  145. {
  146. RegSetValueEx(hkey, REG_STR_CLEAN,
  147. 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
  148. RegCloseKey(hkey);
  149. }
  150. }
  151. BOOL ReadCleanBrowserShutdown()
  152. {
  153. HKEY hkey;
  154. DWORD dwValue = 1; // default to clean shutdown
  155. DWORD dwSize;
  156. //
  157. // Only do MTTF on the first browser session
  158. //
  159. if (GetSessionCount() != 0)
  160. return TRUE;
  161. if (RegOpenKeyEx(HKEY_CURRENT_USER, REG_STR_IE, 0, KEY_READ, &hkey)
  162. == ERROR_SUCCESS)
  163. {
  164. RegQueryValueEx(hkey, REG_STR_CLEAN, NULL, NULL, (LPBYTE)&dwValue, &dwSize);
  165. RegCloseKey(hkey);
  166. }
  167. return (BOOL)dwValue;
  168. }
  169. void _TweakCurrentDirectory()
  170. {
  171. #ifndef UNIX
  172. TCHAR szPath[MAX_PATH];
  173. if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_DESKTOPDIRECTORY, FALSE))
  174. SetCurrentDirectory(szPath);
  175. #endif
  176. }
  177. BOOL _IsDebuggerPresent()
  178. {
  179. static BOOL bDebugger = -1;
  180. if (bDebugger == -1)
  181. {
  182. bDebugger = FALSE;
  183. // See if a debugger is present and bail on splash screen
  184. // so we don't get in the way of people... This api is only
  185. // present on NT...
  186. if (g_fRunningOnNT)
  187. {
  188. PFNISDEBUGGERPRESENT pfndebugger = (PFNISDEBUGGERPRESENT)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), "IsDebuggerPresent");
  189. if (pfndebugger)
  190. bDebugger = pfndebugger();
  191. }
  192. }
  193. return bDebugger;
  194. }
  195. PCWSTR IEGetArgs(PCWSTR pszCmd)
  196. {
  197. if (*pszCmd == TEXT('\"'))
  198. {
  199. // just strip the first quoted string
  200. while (*++pszCmd)
  201. {
  202. if (*pszCmd == L'\"')
  203. {
  204. pszCmd++;
  205. break;
  206. }
  207. }
  208. }
  209. else
  210. {
  211. while (*pszCmd > TEXT(' '))
  212. pszCmd++;
  213. }
  214. // strip the leading spaces
  215. while (*pszCmd && *pszCmd <= L' ')
  216. pszCmd++;
  217. return pszCmd;
  218. }
  219. PCWSTR EatIExploreArgs(PCWSTR pszArgs)
  220. {
  221. // this switches match the switches that are conumed/checked
  222. // in iexplore\mainloop.cpp. most params are in SHParseIECommandLine
  223. // but these few apply only to IExplore.exe
  224. static const PCWSTR s_pszEatArgs[] =
  225. {
  226. L"-eval",
  227. L"-new",
  228. L"-nowait"
  229. };
  230. pszArgs = IEGetArgs(pszArgs);
  231. for (int i = 0; i < ARRAYSIZE(s_pszEatArgs); i++)
  232. {
  233. int cch = lstrlenW(s_pszEatArgs[i]);
  234. if (0 == StrCmpNIW(s_pszEatArgs[i], pszArgs, cch))
  235. {
  236. if (!pszArgs[cch] || pszArgs[cch] == L' ')
  237. pszArgs += cch;
  238. // strip the spaces
  239. while (pszArgs[0] == L' ')
  240. pszArgs++;
  241. // start over, we need to go through this list until we get them all
  242. i = -1;
  243. }
  244. }
  245. return pszArgs;
  246. }
  247. BOOL g_fBrowserOnlyProcess = FALSE;
  248. // this entry is used by IEXPLORE.EXE to run the browser in a separate process. this is the
  249. // standard setting, but browsers (IE) can also be run in the same process if BrowseInSeparateProcess
  250. // is turned off (for better perf, worse stability)
  251. STDAPI_(int) IEWinMain(LPSTR pszCmdLine, int nCmdShow)
  252. {
  253. // this flag indicates that this
  254. // browser is running in its own process
  255. // and is not integrated with the shell
  256. // even if it is running on an intgrated shell
  257. g_fBrowserOnlyProcess = TRUE;
  258. _TweakCurrentDirectory();
  259. if (g_dwProfileCAP & 0x00000001)
  260. StartCAP();
  261. #ifdef FULL_DEBUG
  262. // Turn off GDI batching so that paints are performed immediately
  263. GdiSetBatchLimit(1);
  264. #endif
  265. ASSERT(g_tidParking == 0);
  266. g_tidParking = GetCurrentThreadId();
  267. ISplashScreen *pSplash = NULL;
  268. #ifndef UNIX
  269. // Show splash screen, be simple for beta 1...
  270. if (!_IsDebuggerPresent())
  271. {
  272. if (SUCCEEDED(SHCreateSplashScreen(&pSplash)))
  273. {
  274. HWND hSplash;
  275. pSplash->Show( HINST_THISDLL, -1, -1, &hSplash );
  276. }
  277. }
  278. #endif
  279. if (SUCCEEDED(OleInitialize(NULL)))
  280. {
  281. BOOL fWeOwnWinList = WinList_Init();
  282. IETHREADPARAM* piei = SHCreateIETHREADPARAM(NULL, nCmdShow, NULL, NULL);
  283. if (piei)
  284. {
  285. //
  286. // Create favorites dir (by hand if necessary).
  287. //
  288. InitFavoritesDir();
  289. //
  290. // If we are opening IE with no parameter, check if this is
  291. // the very first open.
  292. //
  293. piei->pSplash = pSplash;
  294. if (pszCmdLine && pszCmdLine[0])
  295. {
  296. USES_CONVERSION;
  297. // we are passed the an ANSI cmd line from IExplore.exe
  298. // this is lame on NT when we can have UNICODE file names.
  299. // on win9x, of course, GetCommandLineW() will return NULL
  300. // so we use the one passed to use from IExplore.exe
  301. LPCWSTR pwszCmdLine;
  302. if (IsOS(OS_NT))
  303. pwszCmdLine = EatIExploreArgs(GetCommandLineW());
  304. else
  305. pwszCmdLine = A2W(pszCmdLine);
  306. SHParseIECommandLine(&pwszCmdLine, piei);
  307. // If the "-channelband" option is selected, turn it ON by default
  308. #ifdef ENABLE_CHANNELS
  309. if (piei->fDesktopChannel)
  310. ChanBarSetAutoLaunchRegValue(TRUE);
  311. #endif // ENABLE_CHANNELS
  312. piei->pszCmdLine = StrDupW(pwszCmdLine);
  313. }
  314. else
  315. {
  316. piei->fCheckFirstOpen = TRUE;
  317. }
  318. #ifdef UNIX
  319. if ( piei->fShouldStart && CheckAndDisplayEULA() )
  320. {
  321. #ifndef NO_SPLASHSCREEN
  322. // IEUNIX - should show after parsing the commandline options.
  323. if (!_IsDebuggerPresent())
  324. {
  325. if (SUCCEEDED(SHCreateSplashScreen(&pSplash)))
  326. {
  327. HWND hSplash;
  328. pSplash->Show( HINST_THISDLL, -1, -1, &hSplash );
  329. }
  330. }
  331. #endif
  332. #endif
  333. DoTimebomb(NULL);
  334. piei->uFlags |= (COF_CREATENEWWINDOW | COF_NOFINDWINDOW | COF_INPROC | COF_IEXPLORE);
  335. SHOpenFolderWindow(piei);
  336. #ifdef UNIX
  337. } // Start browser only if user accepts the license.
  338. #endif
  339. }
  340. IERevokeClassFactoryObject();
  341. CUrlHistory_CleanUp();
  342. if (fWeOwnWinList)
  343. WinList_Terminate();
  344. CWinInetNotify::GlobalDisable();
  345. InternetSetOption(NULL, INTERNET_OPTION_DIGEST_AUTH_UNLOAD, NULL, 0);
  346. OleUninitialize();
  347. }
  348. ATOMICRELEASE(g_psfInternet);
  349. #ifdef DEBUG
  350. CoFreeUnusedLibraries();
  351. #endif
  352. TraceMsg(TF_SHDTHREAD, "IEWinMain about to call ExitProcess");
  353. if (g_dwProfileCAP & 0x00020000)
  354. StopCAP();
  355. #ifdef UNIX
  356. MwExecuteAtExit();
  357. if (g_dwStopWatchMode)
  358. StopWatchFlush();
  359. #endif
  360. ExitProcess(0);
  361. return TRUE;
  362. }