bool PathProvider(int key, FilePath* result) { // 需要进行值的计算. 支持长于MAX_PATH的路径会更好, 但是系统函数设计的时候 // 除了GetTempPath以外都不支持. wchar_t system_buffer[MAX_PATH] = { 0 }; system_buffer[0] = 0; FilePath cur; switch(key) { case DIR_CURRENT: if(!FilePath::GetCurrentDirectory(cur)) { return false; } break; case DIR_EXE: GetModuleFileNameW(NULL, system_buffer, MAX_PATH); cur = FilePath(system_buffer); cur.RemoveFileSpec(); break; case DIR_MODULE: { // 代码调用的模块都有资源, 无论dll或exe. HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); ::GetModuleFileNameW(this_module, system_buffer, MAX_PATH); cur = FilePath(system_buffer); cur.RemoveFileSpec(); break; } case DIR_TEMP: if(!FilePath::GetTempDir(cur)) { return false; } break; case FILE_EXE: GetModuleFileNameW(NULL, system_buffer, MAX_PATH); cur = FilePath(system_buffer); break; case FILE_MODULE: { // 代码调用的模块都有资源, 无论dll或exe. HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); GetModuleFileNameW(this_module, system_buffer, MAX_PATH); cur = FilePath(system_buffer); break; } case DIR_WINDOWS: GetWindowsDirectoryW(system_buffer, MAX_PATH); cur = FilePath(system_buffer); break; case DIR_SYSTEM: GetSystemDirectoryW(system_buffer, MAX_PATH); cur = FilePath(system_buffer); break; case DIR_PROGRAM_FILES: if(FAILED(SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; case DIR_IE_INTERNET_CACHE: if(FAILED(SHGetFolderPathW(NULL, CSIDL_INTERNET_CACHE, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; case DIR_COMMON_START_MENU: if(FAILED(SHGetFolderPathW(NULL, CSIDL_COMMON_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; case DIR_START_MENU: if(FAILED(SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; case DIR_COMMON_APP_DATA: if(FAILED(SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; case DIR_APP_DATA: if(FAILED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; case DIR_PROFILE: if(FAILED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; case DIR_LOCAL_APP_DATA_LOW: if(GetWinVersion() < WINVERSION_VISTA) { return false; } // TODO: 应该使用SHGetKnownFolderPath替换. Bug 1281128. if(FAILED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); cur.RemoveFileSpec(); cur.Append(L"LocalLow"); break; case DIR_LOCAL_APP_DATA: if(FAILED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, system_buffer))) { return false; } cur = FilePath(system_buffer); break; default: return false; } *result = cur; return true; }
bool Root::init(FileString homeDirectory, FileString subprocessDirectory, unsigned int extra_argc, const char* extra_argv[] ) { new base::AtExitManager(); FilePath subprocess; // convert extra arguments in a more useful form std::vector< std::string > extra_args; if( extra_argc > 0 ) { for( unsigned int arg_idx = 0; arg_idx < extra_argc; ++arg_idx ) { const char* raw_arg = extra_argv[ arg_idx ]; assert( raw_arg ); extra_args.push_back( raw_arg ); } } { // From <base/command_line.h>: // Initialize the current process CommandLine singleton. On Windows, // ignores its arguments (we instead parse GetCommandLineW() // directly) because we don't trust the CRT's parsing of the command // line, but it still must be called to set up the command line. // This means that on windows, we have to call ::Init with whatever we feel // like (since this is the only way to create the static CommandLine instance), // and then we have manually call ParseFromString. // (InitFromArgv does not exist on OS_WIN!) #if defined(OS_WIN) FilePath module_dir; if (subprocessDirectory.size()) { module_dir = FilePath(subprocessDirectory.get<FilePath::StringType>()); } else { PathService::Get(base::DIR_MODULE, &module_dir); } #ifdef _DEBUG subprocess = module_dir.Append(L"berkelium_d.exe"); #else subprocess = module_dir.Append(L"berkelium.exe"); #endif std::wstring subprocess_str = L"berkelium --enable-webgl --browser-subprocess-path="; subprocess_str += L"\""; subprocess_str += subprocess.value(); subprocess_str += L"\""; // add extra arguments if any if( !extra_args.empty() ) { for( unsigned int arg_idx = 0, arg_count = extra_args.size(); arg_idx < arg_count; ++arg_idx ) { const std::string& str_arg = extra_args[ arg_idx ]; std::wstring wstr_arg( str_arg.begin(), str_arg.end() ); subprocess_str += L" " + wstr_arg; } } //std::wcout << "Berkelium subprocess_str : " << subprocess_str; CommandLine::Init(0, NULL); CommandLine::ForCurrentProcess()->ParseFromString(subprocess_str); #elif defined(OS_MACOSX) FilePath app_contents; PathService::Get(base::FILE_EXE, &app_contents); FilePath module_dir; if (subprocessDirectory.size()) { module_dir = FilePath(subprocessDirectory.get<FilePath::StringType>()); } else { module_dir = app_contents.DirName(); } subprocess = module_dir.Append("berkelium"); std::string subprocess_str = "--browser-subprocess-path="; subprocess_str += subprocess.value(); std::vector<const char*> argv; argv.push_back( "berkelium" ); argv.push_back( subprocess_str.c_str() ); argv.push_back( "--enable-webgl" ); for( std::vector<std::string>::iterator it = extra_args.begin(); it != extra_args.end(); ++it ) { argv.push_back( it->c_str() ); } //for( std::vector<const char*>::iterator it = argv.begin(); it != argv.end(); ++it ) // std::cout << "Berkelium arg : " << *it; CommandLine::Init( argv.size(), &argv[0] ); #elif defined(OS_POSIX) FilePath module_file; PathService::Get(base::FILE_EXE, &module_file); FilePath module_dir; if (subprocessDirectory.size()) { module_dir = FilePath(subprocessDirectory.get<FilePath::StringType>()); } else { module_dir = module_file.DirName(); } subprocess = module_dir.Append("berkelium"); std::string subprocess_str = "--browser-subprocess-path="; subprocess_str += subprocess.value(); std::vector<const char*> argv; argv.push_back( "berkelium" ); argv.push_back( subprocess_str.c_str() ); argv.push_back( "--enable-webgl" ); for( std::vector<std::string>::iterator it = extra_args.begin(); it != extra_args.end(); ++it ) { argv.push_back( it->c_str() ); } //for( std::vector<const char*>::iterator it = argv.begin(); it != argv.end(); ++it ) // std::cout << "Berkelium arg : " << *it; CommandLine::Init( argv.size(), &argv[0]) ; #endif } PathService::Override(base::FILE_EXE, subprocess); #if !defined(OS_WIN) /// Temporary SingletonLock fix: // Do not do this for child processes--they should only be initialized. // Children should never delete the lock. if (signal(SIGINT, handleINT) == SIG_IGN) { signal(SIGINT, SIG_IGN); } if (signal(SIGHUP, handleINT) == SIG_IGN) { signal(SIGHUP, SIG_IGN); } if (signal(SIGTERM, handleINT) == SIG_IGN) { signal(SIGTERM, SIG_IGN); } #endif chrome::RegisterPathProvider(); ui::RegisterPathProvider(); FilePath homedirpath; if (homeDirectory.data() && homeDirectory.length()) { FilePath homeDirectoryPath(homeDirectory.get<FilePath::StringType>()); PathService::Override(chrome::DIR_USER_DATA, homeDirectoryPath); PathService::Override(chrome::DIR_LOGS, homeDirectoryPath); #if defined(OS_POSIX) PathService::Override(base::DIR_CACHE, homeDirectoryPath); #endif } else { mTempProfileDir.reset(new ScopedTempDir()); if (mTempProfileDir->CreateUniqueTempDir()) { PathService::Override(chrome::DIR_USER_DATA, mTempProfileDir->path()); PathService::Override(chrome::DIR_LOGS, mTempProfileDir->path()); #if defined(OS_POSIX) PathService::Override(base::DIR_CACHE, mTempProfileDir->path()); #endif } } PathService::Get(chrome::DIR_USER_DATA,&homedirpath); bool SINGLE_PROCESS=false; #if defined(OS_MACOSX) base::mac::SetOverrideAppBundlePath(chrome::GetFrameworkBundlePath()); if (SINGLE_PROCESS) { InitWebCoreSystemInterface(); //CGColorSpaceCreateDeviceRGB(); } #endif // OS_MACOSX if (SINGLE_PROCESS) { RenderProcessHost::set_run_renderer_in_process(true); } mMessageLoop.reset(new MessageLoop(MessageLoop::TYPE_UI)); mSysMon.reset(new ui::SystemMonitor); mTimerMgr.reset(new HighResolutionTimerManager); mUIThread.reset(new BrowserThread(BrowserThread::UI, mMessageLoop.get())); mErrorHandler = 0; #if defined(OS_LINUX) if (!g_thread_supported ()) // the client application might have already setup glib { g_thread_init(NULL); // Glib type system initialization. Needed at least for gconf, // used in net/proxy/proxy_config_service_linux.cc. Most likely // this is superfluous as gtk_init() ought to do this. It's // definitely harmless, so retained as a reminder of this // requirement for gconf. g_type_init(); // gtk_init() can change |argc| and |argv|. char argv0data[] = "[Berkelium]"; char *argv0 = argv0data; char **argv = &argv0; int argc = 1; gtk_init(&argc, &argv); } SetUpGLibLogHandler(); #endif mProcessSingleton.reset(new ProcessSingleton(homedirpath)); BrowserProcessImpl *browser_process; browser_process=new BrowserProcessImpl(*CommandLine::ForCurrentProcess()); browser_process->local_state()->RegisterStringPref(prefs::kApplicationLocale, ""); browser_process->local_state()->RegisterBooleanPref(prefs::kMetricsReportingEnabled, false); assert(g_browser_process == browser_process); #ifdef OS_WIN logging::InitLogging( L"chrome.log", logging::LOG_NONE, logging::DONT_LOCK_LOG_FILE, logging::DELETE_OLD_LOG_FILE, logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS ); #else logging::InitLogging( "chrome.log", logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, logging::DONT_LOCK_LOG_FILE, logging::DELETE_OLD_LOG_FILE, logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS ); #endif logging::InitChromeLogging( *CommandLine::ForCurrentProcess(), logging::DELETE_OLD_LOG_FILE); //APPEND_TO_OLD_LOG_FILE chrome::RegisterChromeSchemes(); // Required for "chrome-extension://" in InitExtensions #if defined(OS_LINUX) const char* sandbox_binary = NULL; struct stat st; // In Chromium branded builds, developers can set an environment variable to // use the development sandbox. See // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid()) sandbox_binary = getenv("CHROME_DEVEL_SANDBOX"); std::string sandbox_cmd; if (sandbox_binary && !CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox)) sandbox_cmd = sandbox_binary; // Tickle the sandbox host and zygote host so they fork now. RenderSandboxHostLinux* shost = RenderSandboxHostLinux::GetInstance(); shost->Init(sandbox_cmd); ZygoteHost* zhost = ZygoteHost::GetInstance(); zhost->Init(sandbox_cmd); // We want to be sure to init NSPR on the main thread. base::EnsureNSPRInit(); #endif // defined(OS_LINUX) SandboxInitWrapper sandbox_wrapper; #if defined(OS_WIN) // Get the interface pointer to the BrokerServices or TargetServices, // depending who we are. sandbox::SandboxInterfaceInfo sandbox_info = {0}; sandbox_info.broker_services = sandbox::BrokerServicesBase::GetInstance(); sandbox::InitBrokerServices(sandbox_info.broker_services); if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox)) { bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableAltWinstation); // Precreate the desktop and window station used by the renderers. sandbox::TargetPolicy* policy = sandbox_info.broker_services->CreatePolicy(); sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta); CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); policy->Release(); } sandbox_wrapper.SetServices(&sandbox_info); #endif sandbox_wrapper.InitializeSandbox(*CommandLine::ForCurrentProcess(), ""); bool icu_result = icu_util::Initialize(); CHECK(icu_result); mRenderViewHostFactory.reset(new MemoryRenderViewHostFactory); // mNotificationService=new NotificationService(); // ChildProcess* coreProcess=new ChildProcess; // coreProcess->set_main_thread(new ChildThread); g_browser_process->SetApplicationLocale("en-US"); ResourceBundle::InitSharedInstance("en-US");// FIXME: lookup locale // We only load the theme dll in the browser process. net::CookieMonster::EnableFileScheme(); browser_process->profile_manager(); browser_process->db_thread(); browser_process->file_thread(); browser_process->process_launcher_thread(); browser_process->cache_thread(); browser_process->io_thread(); // Initialize histogram synchronizer system. This is a singleton and is used // for posting tasks via NewRunnableMethod. Its deleted when it goes out of // scope. Even though NewRunnableMethod does AddRef and Release, the object // will not be deleted after the Task is executed. mHistogramSynchronizer= (new HistogramSynchronizer()); browser::RegisterLocalState(g_browser_process->local_state()); ProfileManager* profile_manager = browser_process->profile_manager(); homedirpath = homedirpath.Append(profile_manager->GetCurrentProfileDir()); { //std::cout << "Profile path: " << homedirpath.value() << std::endl; FilePath prefs_path (ProfileManager::GetProfilePrefsPath(homedirpath)); FILE *fp = file_util::OpenFile(prefs_path, "a"); file_util::CloseFile(fp); FilePath history_path (homedirpath); history_path = history_path.Append(chrome::kHistoryFilename); //std::cout << " Profile exists: " << ProfileManager::IsProfile(homedirpath) << std::endl; } mProf = profile_manager->GetProfile(homedirpath, false); if (!mProf) { mProcessSingleton.reset(); return false; } mProf->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, false); mProf->GetPrefs()->RegisterStringPref(prefs::kSafeBrowsingClientKey, ""); mProf->GetPrefs()->RegisterStringPref(prefs::kSafeBrowsingWrappedKey, ""); mProf->InitExtensions(); PrefService* user_prefs = mProf->GetPrefs(); DCHECK(user_prefs); // browser_process->local_state()->SetString(prefs::kApplicationLocale,std::wstring()); mProcessSingleton->Create(); mDNSPrefetch.reset(new chrome_browser_net::PredictorInit( user_prefs, browser_process->local_state(), CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePreconnect))); BrowserURLHandler::InitURLHandlers(); // From chrome/browser/browser_main.cc // Register our global network handler for chrome:// and // chrome-extension:// URLs. ChromeURLDataManagerBackend::Register(); /* RegisterExtensionProtocols(); RegisterMetadataURLRequestHandler(); RegisterBlobURLRequestJobFactory(); RegisterFileSystemURLRequestJobFactory(); */ { FilePath plugindata = homedirpath.AppendASCII("plugin_"); if (!file_util::CreateDirectory(plugindata)) { return false; } PluginService::GetInstance()->SetChromePluginDataDir(plugindata); } PluginService::GetInstance()->LoadChromePlugins( g_browser_process->resource_dispatcher_host()); mDefaultRequestContext=mProf->GetRequestContext(); if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kRemoteDebuggingPort)) { std::string debugging_port_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kRemoteDebuggingPort); int64 debugging_port = -1; bool has_debugging_port = base::StringToInt64(debugging_port_str, &debugging_port); if (has_debugging_port && debugging_port > 0 && debugging_port < 65535) { devtools_http_handler_ = Berkelium::DevToolsHttpProtocolHandler::Start( "127.0.0.1", static_cast<int>(debugging_port), "" ); } } return true; }