Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: chrome/browser/enumerate_modules_model_win.cc

Issue 5092007: Add registered shell extensions to enumerated module list on about:conflicts.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #include "chrome/browser/enumerate_modules_model_win.h" 5 #include "chrome/browser/enumerate_modules_model_win.h"
6 6
7 #include <Tlhelp32.h> 7 #include <Tlhelp32.h>
8 #include <wintrust.h> 8 #include <wintrust.h>
9 9
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "app/win_util.h" 11 #include "app/win_util.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/environment.h" 13 #include "base/environment.h"
14 #include "base/file_path.h" 14 #include "base/file_path.h"
15 #include "base/file_version_info_win.h" 15 #include "base/file_version_info_win.h"
16 #include "base/scoped_handle.h" 16 #include "base/scoped_handle.h"
17 #include "base/sha2.h" 17 #include "base/sha2.h"
18 #include "base/string_number_conversions.h" 18 #include "base/string_number_conversions.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
21 #include "base/values.h" 21 #include "base/values.h"
22 #include "base/version.h" 22 #include "base/version.h"
23 #include "base/win/registry.h"
23 #include "chrome/browser/net/service_providers_win.h" 24 #include "chrome/browser/net/service_providers_win.h"
24 #include "chrome/common/chrome_constants.h" 25 #include "chrome/common/chrome_constants.h"
25 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/notification_service.h" 27 #include "chrome/common/notification_service.h"
27 #include "grit/generated_resources.h" 28 #include "grit/generated_resources.h"
28 29
29 // The period of time (in milliseconds) to wait until checking to see if any 30 // The period of time (in milliseconds) to wait until checking to see if any
30 // incompatible modules exist. 31 // incompatible modules exist.
31 static const int kModuleCheckDelayMs = 60 * 1000; 32 static const int kModuleCheckDelayMs = 60 * 1000;
32 33
34 // The path to the Shell Extension key in the Windows registry.
35 static const wchar_t kRegPath[] =
36 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
37
33 // A sort method that sorts by ModuleType ordinal (loaded module at the top), 38 // A sort method that sorts by ModuleType ordinal (loaded module at the top),
34 // then by full name (including path). 39 // then by full name (including path).
35 static bool ModuleSort(const ModuleEnumerator::Module& a, 40 static bool ModuleSort(const ModuleEnumerator::Module& a,
36 const ModuleEnumerator::Module& b) { 41 const ModuleEnumerator::Module& b) {
37 if (a.type != b.type) 42 if (a.type != b.type)
38 return a.type < b.type; 43 return a.type < b.type;
39 if (a.location == b.location) 44 if (a.location == b.location)
40 return a.name < b.name; 45 return a.name < b.name;
41 46
42 return a.location < b.location; 47 return a.location < b.location;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 BrowserThread::FILE, FROM_HERE, 224 BrowserThread::FILE, FROM_HERE,
220 NewRunnableMethod(this, &ModuleEnumerator::ScanOnFileThread)); 225 NewRunnableMethod(this, &ModuleEnumerator::ScanOnFileThread));
221 } 226 }
222 227
223 void ModuleEnumerator::ScanOnFileThread() { 228 void ModuleEnumerator::ScanOnFileThread() {
224 enumerated_modules_->clear(); 229 enumerated_modules_->clear();
225 230
226 // Make sure the path mapping vector is setup so we can collapse paths. 231 // Make sure the path mapping vector is setup so we can collapse paths.
227 PreparePathMappings(); 232 PreparePathMappings();
228 233
234 EnumerateLoadedModules();
235 EnumerateShellExtensions();
236 EnumerateWinsockModule();
237
238 MatchAgainstBlacklist();
239
240 std::sort(enumerated_modules_->begin(),
241 enumerated_modules_->end(), ModuleSort);
242
243 // Send a reply back on the UI thread.
244 BrowserThread::PostTask(
245 callback_thread_id_, FROM_HERE,
246 NewRunnableMethod(this, &ModuleEnumerator::ReportBack));
247 }
248
249 void ModuleEnumerator::EnumerateLoadedModules() {
229 // Get all modules in the current process. 250 // Get all modules in the current process.
230 ScopedHandle snap(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 251 ScopedHandle snap(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
231 ::GetCurrentProcessId())); 252 ::GetCurrentProcessId()));
232 if (!snap.Get()) 253 if (!snap.Get())
233 return; 254 return;
234 255
235 // Walk the module list. 256 // Walk the module list.
236 MODULEENTRY32 module = { sizeof(module) }; 257 MODULEENTRY32 module = { sizeof(module) };
237 if (!::Module32First(snap.Get(), &module)) 258 if (!::Module32First(snap.Get(), &module))
238 return; 259 return;
239 260
240 do { 261 do {
241 // It would be weird to present chrome.exe as a loaded module. 262 // It would be weird to present chrome.exe as a loaded module.
242 if (_wcsicmp(chrome::kBrowserProcessExecutableName, module.szModule) == 0) 263 if (_wcsicmp(chrome::kBrowserProcessExecutableName, module.szModule) == 0)
243 continue; 264 continue;
244 265
245 Module entry; 266 Module entry;
246 entry.type = LOADED_MODULE; 267 entry.type = LOADED_MODULE;
247 entry.status = NOT_MATCHED;
248 entry.normalized = false;
249 entry.location = module.szExePath; 268 entry.location = module.szExePath;
250 entry.digital_signer = 269 PopulateModuleInformation(&entry);
251 GetSubjectNameFromDigitalSignature(FilePath(entry.location));
252 entry.recommended_action = NONE;
253 scoped_ptr<FileVersionInfo> version_info(
254 FileVersionInfo::CreateFileVersionInfo(FilePath(entry.location)));
255 if (version_info.get()) {
256 FileVersionInfoWin* version_info_win =
257 static_cast<FileVersionInfoWin*>(version_info.get());
258
259 VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info();
260 if (fixed_file_info) {
261 entry.description = version_info_win->file_description();
262 entry.version = version_info_win->file_version();
263 entry.product_name = version_info_win->product_name();
264 }
265 }
266 270
267 NormalizeModule(&entry); 271 NormalizeModule(&entry);
268 CollapsePath(&entry); 272 CollapsePath(&entry);
269 enumerated_modules_->push_back(entry); 273 enumerated_modules_->push_back(entry);
270 } while (::Module32Next(snap.Get(), &module)); 274 } while (::Module32Next(snap.Get(), &module));
275 }
271 276
277 void ModuleEnumerator::EnumerateShellExtensions() {
278 base::win::RegistryValueIterator registration(HKEY_LOCAL_MACHINE, kRegPath);
huanr 2010/11/18 22:01:13 Do you need to enumerate keys under HKCU?
279 while (registration.Valid()) {
280 std::wstring key(std::wstring(L"CLSID\\") + registration.Name() +
281 L"\\InProcServer32");
282 base::win::RegKey clsid;
283 if (!clsid.Open(HKEY_CLASSES_ROOT, key.c_str(), KEY_READ)) {
284 ++registration;
285 continue;
286 }
287 string16 dll;
288 if (!clsid.ReadValue(L"", &dll)) {
289 ++registration;
290 continue;
291 }
292 clsid.Close();
293
294 Module entry;
295 entry.type = SHELL_EXTENSION;
296 entry.location = dll;
297 PopulateModuleInformation(&entry);
298
299 NormalizeModule(&entry);
300 CollapsePath(&entry);
301 enumerated_modules_->push_back(entry);
302
303 ++registration;
304 }
305 }
306
307 void ModuleEnumerator::EnumerateWinsockModule() {
272 // Add to this list the Winsock LSP DLLs. 308 // Add to this list the Winsock LSP DLLs.
273 WinsockLayeredServiceProviderList layered_providers; 309 WinsockLayeredServiceProviderList layered_providers;
274 GetWinsockLayeredServiceProviders(&layered_providers); 310 GetWinsockLayeredServiceProviders(&layered_providers);
275 for (size_t i = 0; i < layered_providers.size(); ++i) { 311 for (size_t i = 0; i < layered_providers.size(); ++i) {
276 Module entry; 312 Module entry;
277 entry.type = WINSOCK_MODULE_REGISTRATION; 313 entry.type = WINSOCK_MODULE_REGISTRATION;
278 entry.status = NOT_MATCHED; 314 entry.status = NOT_MATCHED;
279 entry.normalized = false; 315 entry.normalized = false;
280 entry.location = layered_providers[i].path; 316 entry.location = layered_providers[i].path;
281 entry.description = layered_providers[i].name; 317 entry.description = layered_providers[i].name;
282 entry.recommended_action = NONE; 318 entry.recommended_action = NONE;
283 319
284 wchar_t expanded[MAX_PATH]; 320 wchar_t expanded[MAX_PATH];
285 DWORD size = ExpandEnvironmentStrings( 321 DWORD size = ExpandEnvironmentStrings(
286 entry.location.c_str(), expanded, MAX_PATH); 322 entry.location.c_str(), expanded, MAX_PATH);
287 if (size != 0 && size <= MAX_PATH) { 323 if (size != 0 && size <= MAX_PATH) {
288 entry.digital_signer = 324 entry.digital_signer =
289 GetSubjectNameFromDigitalSignature(FilePath(expanded)); 325 GetSubjectNameFromDigitalSignature(FilePath(expanded));
290 } 326 }
291 entry.version = base::IntToString16(layered_providers[i].version); 327 entry.version = base::IntToString16(layered_providers[i].version);
292 328
293 // Paths have already been collapsed. 329 // Paths have already been collapsed.
294 NormalizeModule(&entry); 330 NormalizeModule(&entry);
295 enumerated_modules_->push_back(entry); 331 enumerated_modules_->push_back(entry);
296 } 332 }
333 }
297 334
298 MatchAgainstBlacklist(); 335 void ModuleEnumerator::PopulateModuleInformation(Module* module) {
336 module->status = NOT_MATCHED;
337 module->normalized = false;
338 module->digital_signer =
339 GetSubjectNameFromDigitalSignature(FilePath(module->location));
340 module->recommended_action = NONE;
341 scoped_ptr<FileVersionInfo> version_info(
342 FileVersionInfo::CreateFileVersionInfo(FilePath(module->location)));
343 if (version_info.get()) {
344 FileVersionInfoWin* version_info_win =
345 static_cast<FileVersionInfoWin*>(version_info.get());
299 346
300 std::sort(enumerated_modules_->begin(), 347 VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info();
301 enumerated_modules_->end(), ModuleSort); 348 if (fixed_file_info) {
302 349 module->description = version_info_win->file_description();
303 // Send a reply back on the UI thread. 350 module->version = version_info_win->file_version();
304 BrowserThread::PostTask( 351 module->product_name = version_info_win->product_name();
305 callback_thread_id_, FROM_HERE, 352 }
306 NewRunnableMethod(this, &ModuleEnumerator::ReportBack)); 353 }
307 } 354 }
308 355
309 void ModuleEnumerator::PreparePathMappings() { 356 void ModuleEnumerator::PreparePathMappings() {
310 path_mapping_.clear(); 357 path_mapping_.clear();
311 358
312 scoped_ptr<base::Environment> environment(base::Environment::Create()); 359 scoped_ptr<base::Environment> environment(base::Environment::Create());
313 std::vector<string16> env_vars; 360 std::vector<string16> env_vars;
314 env_vars.push_back(L"LOCALAPPDATA"); 361 env_vars.push_back(L"LOCALAPPDATA");
315 env_vars.push_back(L"ProgramFiles"); 362 env_vars.push_back(L"ProgramFiles");
316 env_vars.push_back(L"USERPROFILE"); 363 env_vars.push_back(L"USERPROFILE");
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 return NULL; 538 return NULL;
492 } 539 }
493 540
494 ListValue* list = new ListValue(); 541 ListValue* list = new ListValue();
495 542
496 for (ModuleEnumerator::ModulesVector::const_iterator module = 543 for (ModuleEnumerator::ModulesVector::const_iterator module =
497 enumerated_modules_.begin(); 544 enumerated_modules_.begin();
498 module != enumerated_modules_.end(); ++module) { 545 module != enumerated_modules_.end(); ++module) {
499 DictionaryValue* data = new DictionaryValue(); 546 DictionaryValue* data = new DictionaryValue();
500 data->SetInteger("type", module->type); 547 data->SetInteger("type", module->type);
501 data->SetString("type_description", 548 switch (module->type) {
502 (module->type == ModuleEnumerator::WINSOCK_MODULE_REGISTRATION) ? 549 case ModuleEnumerator::SHELL_EXTENSION:
503 ASCIIToWide("Winsock") : ASCIIToWide("")); 550 data->SetString("type_description", ASCIIToWide("Shell Extension"));
551 break;
552 case ModuleEnumerator::WINSOCK_MODULE_REGISTRATION:
553 data->SetString("type_description", ASCIIToWide("Winsock"));
554 break;
555 default:
556 data->SetString("type_description", ASCIIToWide(""));
557 break;
558 }
504 data->SetInteger("status", module->status); 559 data->SetInteger("status", module->status);
505 data->SetString("location", module->location); 560 data->SetString("location", module->location);
506 data->SetString("name", module->name); 561 data->SetString("name", module->name);
507 data->SetString("product_name", module->product_name); 562 data->SetString("product_name", module->product_name);
508 data->SetString("description", module->description); 563 data->SetString("description", module->description);
509 data->SetString("version", module->version.empty() ? ASCIIToWide("") : 564 data->SetString("version", module->version.empty() ? ASCIIToWide("") :
510 l10n_util::GetStringF(IDS_CONFLICTS_CHECK_VERSION_STRING, 565 l10n_util::GetStringF(IDS_CONFLICTS_CHECK_VERSION_STRING,
511 module->version)); 566 module->version));
512 data->SetString("digital_signer", module->digital_signer); 567 data->SetString("digital_signer", module->digital_signer);
513 568
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 GenerateHash(WideToUTF8(module.name), &filename); 665 GenerateHash(WideToUTF8(module.name), &filename);
611 GenerateHash(WideToUTF8(module.location), &location); 666 GenerateHash(WideToUTF8(module.location), &location);
612 GenerateHash(WideToUTF8(module.description), &description); 667 GenerateHash(WideToUTF8(module.description), &description);
613 GenerateHash(WideToUTF8(module.digital_signer), &signer); 668 GenerateHash(WideToUTF8(module.digital_signer), &signer);
614 669
615 string16 url = l10n_util::GetStringF(IDS_HELP_CENTER_VIEW_CONFLICTS, 670 string16 url = l10n_util::GetStringF(IDS_HELP_CENTER_VIEW_CONFLICTS,
616 ASCIIToWide(filename), ASCIIToWide(location), 671 ASCIIToWide(filename), ASCIIToWide(location),
617 ASCIIToWide(description), ASCIIToWide(signer)); 672 ASCIIToWide(description), ASCIIToWide(signer));
618 return GURL(WideToUTF8(url)); 673 return GURL(WideToUTF8(url));
619 } 674 }
OLDNEW
« no previous file with comments | « chrome/browser/enumerate_modules_model_win.h ('k') | chrome/browser/resources/about_conflicts.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698