| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // For WinDDK ATL compatibility, these ATL headers must come first. | 5 #include "chrome/browser/plugin_database_handler.h" |
| 6 #include <atlbase.h> | |
| 7 #include <atlwin.h> | |
| 8 | |
| 9 #include "chrome/default_plugin/plugin_database_handler.h" | |
| 10 | 6 |
| 11 #include "libxml/parser.h" | 7 #include "libxml/parser.h" |
| 12 #include "libxml/xpath.h" | 8 #include "libxml/xpath.h" |
| 13 | 9 |
| 14 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 15 #include "base/path_service.h" | 11 #include "base/path_service.h" |
| 16 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
| 17 #include "base/string_split.h" | 13 #include "base/string_split.h" |
| 18 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 19 #include "base/time.h" | 15 #include "base/time.h" |
| 20 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 21 #include "chrome/default_plugin/plugin_impl.h" | |
| 22 #include "chrome/default_plugin/plugin_main.h" | |
| 23 | 17 |
| 24 using base::Time; | 18 using base::Time; |
| 25 using base::TimeDelta; | 19 using base::TimeDelta; |
| 26 | 20 |
| 27 PluginDatabaseHandler::PluginDatabaseHandler( | 21 PluginDatabaseHandler::PluginDatabaseHandler() |
| 28 PluginInstallerImpl& plugin_installer_instance) | 22 : plugin_downloads_file_(base::kInvalidPlatformFileValue), |
| 29 : plugin_downloads_file_(INVALID_HANDLE_VALUE), | |
| 30 plugin_installer_instance_(plugin_installer_instance), | |
| 31 ignore_plugin_db_data_(false) { | 23 ignore_plugin_db_data_(false) { |
| 32 } | 24 } |
| 33 | 25 |
| 34 PluginDatabaseHandler::~PluginDatabaseHandler() { | 26 PluginDatabaseHandler::~PluginDatabaseHandler() { |
| 35 if (plugin_downloads_file_ != INVALID_HANDLE_VALUE) { | 27 Close(false); |
| 36 ::CloseHandle(plugin_downloads_file_); | |
| 37 plugin_downloads_file_ = INVALID_HANDLE_VALUE; | |
| 38 } | |
| 39 } | 28 } |
| 40 | 29 |
| 41 bool PluginDatabaseHandler::DownloadPluginsFileIfNeeded( | 30 bool PluginDatabaseHandler::DownloadPluginsFileIfNeeded( |
| 42 const std::string& plugin_finder_url) { | 31 const std::string& plugin_finder_url, |
| 32 PluginDatabaseHandler::Client* client) { |
| 43 DCHECK(!plugin_finder_url.empty()); | 33 DCHECK(!plugin_finder_url.empty()); |
| 44 // The time in days for which the plugins list is cached. | 34 // The time in days for which the plugins list is cached. |
| 45 // TODO(iyengar) Make this configurable. | 35 // TODO(iyengar) Make this configurable. |
| 46 const int kPluginsListCacheTimeInDays = 3; | 36 const int kPluginsListCacheTimeInDays = 3; |
| 47 | 37 |
| 48 plugin_finder_url_ = plugin_finder_url; | 38 plugin_finder_url_ = plugin_finder_url; |
| 49 | 39 |
| 50 FilePath module_path; | 40 FilePath module_path; |
| 51 PathService::Get(base::DIR_MODULE, &module_path); | 41 PathService::Get(base::DIR_MODULE, &module_path); |
| 52 plugins_file_ = module_path.Append(L"chrome_plugins_file.xml").value(); | 42 plugins_file_ = module_path.Append( |
| 43 FILE_PATH_LITERAL("chrome_plugins_file.xml")); |
| 53 | 44 |
| 54 bool initiate_download = false; | 45 bool initiate_download = false; |
| 55 if (!file_util::PathExists(FilePath(plugins_file_))) { | 46 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| 47 base::PlatformFile file = base::CreatePlatformFile( |
| 48 plugins_file_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, |
| 49 NULL, &error); |
| 50 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) { |
| 56 initiate_download = true; | 51 initiate_download = true; |
| 57 } else { | 52 } else { |
| 58 SYSTEMTIME creation_system_time = {0}; | 53 base::PlatformFileInfo file_info; |
| 59 if (!file_util::GetFileCreationLocalTime(plugins_file_, | 54 if (!base::GetPlatformFileInfo(file, &file_info)) { |
| 60 &creation_system_time)) { | |
| 61 NOTREACHED(); | 55 NOTREACHED(); |
| 62 return false; | 56 return false; |
| 63 } | 57 } |
| 64 | 58 |
| 65 FILETIME creation_file_time = {0}; | 59 Time current_time = Time::Now(); |
| 66 ::SystemTimeToFileTime(&creation_system_time, &creation_file_time); | |
| 67 | 60 |
| 68 FILETIME current_time = {0}; | 61 TimeDelta time_diff = file_info.creation_time - current_time; // ??? |
| 69 ::GetSystemTimeAsFileTime(¤t_time); | |
| 70 | |
| 71 Time file_time = Time::FromFileTime(creation_file_time); | |
| 72 Time current_system_time = Time::FromFileTime(current_time); | |
| 73 | |
| 74 TimeDelta time_diff = file_time - current_system_time; | |
| 75 if (time_diff.InDays() > kPluginsListCacheTimeInDays) { | 62 if (time_diff.InDays() > kPluginsListCacheTimeInDays) { |
| 76 initiate_download = true; | 63 initiate_download = true; |
| 77 } | 64 } |
| 78 } | 65 } |
| 79 | 66 |
| 80 if (initiate_download) { | 67 if (initiate_download) { |
| 81 DVLOG(1) << "Initiating GetURLNotify on the plugin finder URL " | 68 DVLOG(1) << "Initiating GetURLNotify on the plugin finder URL " |
| 82 << plugin_finder_url.c_str(); | 69 << plugin_finder_url; |
| 83 | 70 |
| 84 plugin_installer_instance_.set_plugin_installer_state( | 71 client->DownloadPluginList(plugin_finder_url); |
| 85 PluginListDownloadInitiated); | |
| 86 | |
| 87 DCHECK(default_plugin::g_browser->geturlnotify); | |
| 88 default_plugin::g_browser->geturlnotify( | |
| 89 plugin_installer_instance_.instance(), plugin_finder_url.c_str(), | |
| 90 NULL, NULL); | |
| 91 } else { | 72 } else { |
| 92 DVLOG(1) << "Plugins file " << plugins_file_ << " already exists"; | 73 DVLOG(1) << "Plugins file " << plugins_file_.value() << " already exists"; |
| 93 plugin_downloads_file_ = ::CreateFile(plugins_file_.c_str(), GENERIC_READ, | 74 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| 94 FILE_SHARE_READ, NULL, OPEN_EXISTING, | 75 plugin_downloads_file_ = base::CreatePlatformFile( |
| 95 FILE_ATTRIBUTE_NORMAL, NULL); | 76 plugins_file_, |
| 96 if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { | 77 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, |
| 97 DVLOG(1) << "Failed to open plugins file " << plugins_file_ | 78 NULL, |
| 98 << " Error " << ::GetLastError(); | 79 &error); |
| 80 if (error != base::PLATFORM_FILE_OK) { |
| 81 DVLOG(1) << "Failed to open plugins file " << plugins_file_.value() |
| 82 << " Error " << error; |
| 99 NOTREACHED(); | 83 NOTREACHED(); |
| 100 return false; | 84 return false; |
| 101 } | 85 } |
| 102 // The URLNotify function contains all handling needed to parse the plugins | 86 client->OnPluginListDownloaded(); |
| 103 // file and display the UI accordingly. | |
| 104 plugin_installer_instance_.set_plugin_installer_state( | |
| 105 PluginListDownloadInitiated); | |
| 106 plugin_installer_instance_.URLNotify(plugin_finder_url.c_str(), | |
| 107 NPRES_DONE); | |
| 108 } | 87 } |
| 109 return true; | 88 return true; |
| 110 } | 89 } |
| 111 | 90 |
| 112 int32 PluginDatabaseHandler::Write(NPStream* stream, int32 offset, | 91 int32 PluginDatabaseHandler::Write(NPStream* stream, int32 offset, |
| 113 int32 buffer_length, void* buffer) { | 92 int32 buffer_length, void* buffer) { |
| 114 if (ignore_plugin_db_data_) { | 93 if (ignore_plugin_db_data_) { |
| 115 return buffer_length; | 94 return buffer_length; |
| 116 } | 95 } |
| 117 | 96 |
| 118 if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { | 97 if (plugin_downloads_file_ == base::kInvalidPlatformFileValue) { |
| 119 DVLOG(1) << "About to create plugins file " << plugins_file_; | 98 DVLOG(1) << "About to create plugins file " << plugins_file_.value(); |
| 120 plugin_downloads_file_ = CreateFile(plugins_file_.c_str(), | 99 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| 121 GENERIC_READ | GENERIC_WRITE, | 100 plugin_downloads_file_ = base::CreatePlatformFile( |
| 122 FILE_SHARE_READ, NULL, CREATE_ALWAYS, | 101 plugins_file_, |
| 123 FILE_ATTRIBUTE_NORMAL, NULL); | 102 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, |
| 124 if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { | 103 NULL, |
| 125 DWORD error = ::GetLastError(); | 104 &error); |
| 126 if (error == ERROR_SHARING_VIOLATION) { | 105 if (error != base::PLATFORM_FILE_OK) { |
| 106 if (error == base::PLATFORM_FILE_ERROR_IN_USE) { |
| 127 // File may have been downloaded by another plugin instance on this | 107 // File may have been downloaded by another plugin instance on this |
| 128 // page. | 108 // page. |
| 129 plugin_downloads_file_ = ::CreateFile( | 109 plugin_downloads_file_ = base::CreatePlatformFile( |
| 130 plugins_file_.c_str(), GENERIC_READ, | 110 plugins_file_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, |
| 131 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, | 111 NULL, &error); |
| 132 FILE_ATTRIBUTE_NORMAL, NULL); | 112 if (error == base::PLATFORM_FILE_OK) { |
| 133 if (plugin_downloads_file_ != INVALID_HANDLE_VALUE) { | |
| 134 ignore_plugin_db_data_ = true; | 113 ignore_plugin_db_data_ = true; |
| 135 return buffer_length; | 114 return buffer_length; |
| 136 } | 115 } |
| 137 } | 116 } |
| 138 | 117 |
| 139 DLOG(ERROR) << "Failed to create plugins file " << plugins_file_ | 118 DLOG(ERROR) << "Failed to create plugins file " << plugins_file_.value() |
| 140 << " Error " << ::GetLastError(); | 119 << " Error " << error; |
| 141 return 0; | 120 return 0; |
| 142 } | 121 } |
| 143 } | 122 } |
| 144 | 123 |
| 145 DWORD bytes_written = 0; | 124 int bytes_written = 0; |
| 146 if (0 == lstrcmpiA(stream->url, plugin_finder_url_.c_str())) { | 125 if (plugin_finder_url_ == stream->url) { |
| 147 DCHECK(plugin_downloads_file_ != INVALID_HANDLE_VALUE); | 126 DCHECK(plugin_downloads_file_ != base::kInvalidPlatformFileValue); |
| 148 | 127 |
| 149 WriteFile(plugin_downloads_file_, buffer, buffer_length, &bytes_written, | 128 bytes_written = base::WritePlatformFile(plugin_downloads_file_, 0, |
| 150 NULL); | 129 static_cast<const char*>(buffer), |
| 130 buffer_length); |
| 151 DCHECK_EQ(buffer_length, static_cast<int32>(bytes_written)); | 131 DCHECK_EQ(buffer_length, static_cast<int32>(bytes_written)); |
| 152 } | 132 } |
| 153 return bytes_written; | 133 return bytes_written; |
| 154 } | 134 } |
| 155 | 135 |
| 156 | 136 |
| 157 bool PluginDatabaseHandler::ParsePluginList() { | 137 bool PluginDatabaseHandler::ParsePluginList() { |
| 158 if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { | 138 if (plugin_downloads_file_ == base::kInvalidPlatformFileValue) { |
| 159 DLOG(WARNING) << "Invalid plugins file"; | 139 DLOG(WARNING) << "Invalid plugins file"; |
| 160 NOTREACHED(); | 140 NOTREACHED(); |
| 161 return false; | 141 return false; |
| 162 } | 142 } |
| 163 | 143 |
| 164 bool parse_result = false; | 144 bool parse_result = false; |
| 165 | 145 |
| 166 std::string plugins_file = WideToUTF8(plugins_file_.c_str()); | 146 std::string plugins_file; |
| 147 #if defined OS_WIN |
| 148 plugins_file = WideToUTF8(plugins_file_.value()); |
| 149 #else |
| 150 plugins_file = plugins_file_.value(); |
| 151 #endif |
| 167 xmlDocPtr plugin_downloads_doc = xmlParseFile(plugins_file.c_str()); | 152 xmlDocPtr plugin_downloads_doc = xmlParseFile(plugins_file.c_str()); |
| 168 if (plugin_downloads_doc == NULL) { | 153 if (plugin_downloads_doc == NULL) { |
| 169 DLOG(WARNING) << "Failed to parse plugins file " << plugins_file.c_str(); | 154 DLOG(WARNING) << "Failed to parse plugins file " << plugins_file_.value(); |
| 170 return parse_result; | 155 return parse_result; |
| 171 } | 156 } |
| 172 | 157 |
| 173 xmlXPathContextPtr context = NULL; | 158 xmlXPathContextPtr context = NULL; |
| 174 xmlXPathObjectPtr plugins_result = NULL; | 159 xmlXPathObjectPtr plugins_result = NULL; |
| 175 | 160 |
| 176 do { | 161 do { |
| 177 context = xmlXPathNewContext(plugin_downloads_doc); | 162 context = xmlXPathNewContext(plugin_downloads_doc); |
| 178 if (context == NULL) { | 163 if (context == NULL) { |
| 179 DLOG(WARNING) << "Failed to retrieve XPath context"; | 164 DLOG(WARNING) << "Failed to retrieve XPath context"; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 | 196 |
| 212 xmlXPathFreeContext(context); | 197 xmlXPathFreeContext(context); |
| 213 xmlXPathFreeObject(plugins_result); | 198 xmlXPathFreeObject(plugins_result); |
| 214 xmlFreeDoc(plugin_downloads_doc); | 199 xmlFreeDoc(plugin_downloads_doc); |
| 215 xmlCleanupParser(); | 200 xmlCleanupParser(); |
| 216 DVLOG(1) << "Parse plugins file result " << parse_result; | 201 DVLOG(1) << "Parse plugins file result " << parse_result; |
| 217 return parse_result; | 202 return parse_result; |
| 218 } | 203 } |
| 219 | 204 |
| 220 bool PluginDatabaseHandler::GetPluginDetailsForMimeType( | 205 bool PluginDatabaseHandler::GetPluginDetailsForMimeType( |
| 221 const char* mime_type, const char* language, | 206 const std::string& mime_type, const std::string& language, |
| 222 std::string* download_url, std::wstring* plugin_name, | 207 std::string* download_url, string16* plugin_name, |
| 223 bool* download_url_for_display) { | 208 bool* download_url_for_display) { |
| 224 if (!mime_type || !language || !download_url || !plugin_name || | 209 if (mime_type.empty() || language.empty() || !download_url || !plugin_name || |
| 225 !download_url_for_display) { | 210 !download_url_for_display) { |
| 226 NOTREACHED(); | 211 NOTREACHED(); |
| 227 return false; | 212 return false; |
| 228 } | 213 } |
| 229 | 214 |
| 230 PluginList::iterator plugin_index; | 215 PluginList::iterator plugin_index; |
| 231 for (plugin_index = downloaded_plugins_list_.begin(); | 216 for (plugin_index = downloaded_plugins_list_.begin(); |
| 232 plugin_index != downloaded_plugins_list_.end(); | 217 plugin_index != downloaded_plugins_list_.end(); |
| 233 ++plugin_index) { | 218 ++plugin_index) { |
| 234 PluginDetail& current_plugin = *plugin_index; | 219 PluginDetail& current_plugin = *plugin_index; |
| 235 | 220 |
| 236 std::vector<std::string>::iterator mime_type_index; | 221 std::vector<std::string>::iterator mime_type_index; |
| 237 for (mime_type_index = current_plugin.mime_types.begin(); | 222 for (mime_type_index = current_plugin.mime_types.begin(); |
| 238 mime_type_index != current_plugin.mime_types.end(); | 223 mime_type_index != current_plugin.mime_types.end(); |
| 239 ++mime_type_index) { | 224 ++mime_type_index) { |
| 240 if ((0 == lstrcmpiA(mime_type, (*mime_type_index).c_str())) && | 225 if ((*mime_type_index == mime_type) && |
| 241 (0 == lstrcmpiA(language, current_plugin.language.c_str()))) { | 226 (current_plugin.language == language)) { |
| 242 *download_url = current_plugin.download_url; | 227 *download_url = current_plugin.download_url; |
| 243 *plugin_name = current_plugin.display_name; | 228 *plugin_name = current_plugin.display_name; |
| 244 *download_url_for_display = current_plugin.download_url_for_display; | 229 *download_url_for_display = current_plugin.download_url_for_display; |
| 245 return true; | 230 return true; |
| 246 } | 231 } |
| 247 } | 232 } |
| 248 } | 233 } |
| 249 return false; | 234 return false; |
| 250 } | 235 } |
| 251 | 236 |
| 252 void PluginDatabaseHandler::Close(bool delete_file) { | 237 void PluginDatabaseHandler::Close(bool delete_file) { |
| 253 if (plugin_downloads_file_ != INVALID_HANDLE_VALUE) { | 238 if (plugin_downloads_file_ != base::kInvalidPlatformFileValue) { |
| 254 ::CloseHandle(plugin_downloads_file_); | 239 base::ClosePlatformFile(plugin_downloads_file_); |
| 255 plugin_downloads_file_ = INVALID_HANDLE_VALUE; | 240 plugin_downloads_file_ = base::kInvalidPlatformFileValue; |
| 256 if (delete_file) { | 241 if (delete_file) { |
| 257 ::DeleteFile(plugins_file_.c_str()); | 242 bool result = file_util::Delete(plugins_file_, false); |
| 258 plugins_file_.clear(); | 243 DCHECK(result); |
| 244 plugins_file_ = FilePath(); |
| 259 } | 245 } |
| 260 } | 246 } |
| 261 } | 247 } |
| 262 | 248 |
| 263 bool PluginDatabaseHandler::ReadPluginInfo(_xmlNode* plugin_node, | 249 bool PluginDatabaseHandler::ReadPluginInfo( |
| 264 PluginDetail* plugin_detail) { | 250 _xmlNode* plugin_node, |
| 251 PluginDatabaseHandler::PluginDetail* plugin_detail) { |
| 265 static const char kMimeTypeSeparator = ';'; | 252 static const char kMimeTypeSeparator = ';'; |
| 266 | 253 |
| 267 if (!plugin_node) { | 254 if (!plugin_node) { |
| 268 NOTREACHED(); | 255 NOTREACHED(); |
| 269 return false; | 256 return false; |
| 270 } | 257 } |
| 271 | 258 |
| 272 _xmlNode* plugin_mime_type = plugin_node->next; | 259 _xmlNode* plugin_mime_type = plugin_node->next; |
| 273 if ((plugin_mime_type == NULL) || | 260 if ((plugin_mime_type == NULL) || |
| 274 (plugin_mime_type->next == NULL)) { | 261 (plugin_mime_type->next == NULL)) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 int url_for_display = 0; | 323 int url_for_display = 0; |
| 337 base::StringToInt( | 324 base::StringToInt( |
| 338 reinterpret_cast<const char*>(url_for_display_val->content), | 325 reinterpret_cast<const char*>(url_for_display_val->content), |
| 339 &url_for_display); | 326 &url_for_display); |
| 340 if (url_for_display != 0) | 327 if (url_for_display != 0) |
| 341 plugin_detail->download_url_for_display = true; | 328 plugin_detail->download_url_for_display = true; |
| 342 } | 329 } |
| 343 } | 330 } |
| 344 | 331 |
| 345 plugin_detail->display_name = | 332 plugin_detail->display_name = |
| 346 UTF8ToWide(reinterpret_cast<const char*>(plugin_name_val->content)); | 333 UTF8ToUTF16(reinterpret_cast<const char*>(plugin_name_val->content)); |
| 347 plugin_detail->download_url = | 334 plugin_detail->download_url = |
| 348 reinterpret_cast<const char*>(plugin_download_url_val->content); | 335 reinterpret_cast<const char*>(plugin_download_url_val->content); |
| 349 | 336 |
| 350 base::SplitString( | 337 base::SplitString( |
| 351 reinterpret_cast<const char*>(plugin_mime_type_vals->content), | 338 reinterpret_cast<const char*>(plugin_mime_type_vals->content), |
| 352 kMimeTypeSeparator, &plugin_detail->mime_types); | 339 kMimeTypeSeparator, &plugin_detail->mime_types); |
| 353 | 340 |
| 354 plugin_detail->language = | 341 plugin_detail->language = |
| 355 reinterpret_cast<const char*>(plugin_lang_val->content); | 342 reinterpret_cast<const char*>(plugin_lang_val->content); |
| 356 | 343 |
| 357 return true; | 344 return true; |
| 358 } | 345 } |
| 346 |
| 347 PluginDatabaseHandler::PluginDetail::PluginDetail() { |
| 348 } |
| 349 |
| 350 PluginDatabaseHandler::PluginDetail::~PluginDetail() { |
| 351 } |
| OLD | NEW |