我们知道一般的Windows程序都会有一个WinMain函数,Chrome的这个函数在chrome\app\chrome_exe_main_win.cc这个文件中:
- int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {
- // Initialize the commandline singleton from the environment.
- CommandLine::Init(0, NULL);
- // The exit manager is in charge of calling the dtors of singletons.
- base::AtExitManager exit_manager;
- MetroDriver metro_driver;
- if (metro_driver.in_metro_mode())
- return metro_driver.RunInMetro(instance, &RunChrome);
- // Not in metro mode, proceed as normal.
- return RunChrome(instance);
- }
首先,这个函数初始化了CommandLine,它是一个singleton,用来保存和管理当前进程中的所有参数。然后又创建了一个AtExitManager,它是用来负责所有singleton的销毁工作的。若是在Win8下并满足MetroDriver的检测的话,就可能通过MetroDriver::RunInMetro来启动Chrome。下面将详细看一下用的比较多的RunChrome函数。
- int RunChrome(HINSTANCE instance) {
- bool exit_now = true;
- // We restarted because of a previous crash. Ask user if we should relaunch.
- if (ShowRestartDialogIfCrashed(&exit_now)) {
- if (exit_now)
- return content::RESULT_CODE_NORMAL_EXIT;
- }
- // Initialize the sandbox services.
- sandbox::SandboxInterfaceInfo sandbox_info = {0};
- content::InitializeSandboxInfo(&sandbox_info);
- // Load and launch the chrome dll. *Everything* happens inside.
- MainDllLoader* loader = MakeMainDllLoader();
- int rc = loader->Launch(instance, &sandbox_info);
- loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded();
- delete loader;
- return rc;
- }
RunChrome中的第一个先调用ShowRestartDialogIfCrashed,Chrome若是之前崩溃了,这个函数就互弹出一个MessageBox,告诉你崩溃的情况,是否需要再开启Chrome,若要开启,下面的代码再跑一遍,重新打开Chrome。
接下来初始化sandbox,sandbox对象创建完后,必须要用content::InitializeSandboxInfo初始化。
由于,Chrome的实际内容并不在Chrome.exe中,而在Chrome.dll中,所以下面有个创建MainDllLoader对象的过程 —— MakeMainDllLoader()。然后通过这个对象的Launch方法将整个Chrome加载起来,这个方法有两个参数:一个是WinMain中的HINSTANCE,另一个是之前创建的那个sandbox。
- int MainDllLoader::Launch(HINSTANCE instance,
- sandbox::SandboxInterfaceInfo* sbox_info) {
- string16 version;
- string16 file;
- dll_ = Load(&version, &file);
- if (!dll_)
- return chrome::RESULT_CODE_MISSING_DATA;
- scoped_ptr<base::Environment> env(base::Environment::Create());
- env->SetVar(chrome::kChromeVersionEnvVar, WideToUTF8(version));
- InitCrashReporter();
- OnBeforeLaunch(file);
- DLL_MAIN entry_point =
- reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain"));
- if (!entry_point)
- return chrome::RESULT_CODE_BAD_PROCESS_TYPE;
- int rc = entry_point(instance, sbox_info);
- return OnBeforeExit(rc, file);
- }
这个函数中,先通过Load方法将Chrome.dll加载进来,dll_中保存了DLL句柄,下面还有其他一些准备工作。接着在GetProcAddress这里进入正题了,寻找Chrome.dll这个模块中名为ChromeMain的函数,entry_point中保存了这个函数指针,最后通过调用这个函数进到Chrome.dll模块中执行剩余的工作。
转载于:https://blog.51cto.com/rongzh/1127847