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

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 ReadShellExtensions(HKEY_LOCAL_MACHINE);
279 ReadShellExtensions(HKEY_CURRENT_USER);
280 }
281
282 void ModuleEnumerator::ReadShellExtensions(HKEY parent) {
283 base::win::RegistryValueIterator registration(parent, kRegPath);
284 while (registration.Valid()) {
285 std::wstring key(std::wstring(L"CLSID\\") + registration.Name() +
286 L"\\InProcServer32");
287 base::win::RegKey clsid;
288 if (!clsid.Open(HKEY_CLASSES_ROOT, key.c_str(), KEY_READ)) {
289 ++registration;
290 continue;
291 }
292 string16 dll;
293 if (!clsid.ReadValue(L"", &dll)) {
294 ++registration;
295 continue;
296 }
297 clsid.Close();
298
299 Module entry;
300 entry.type = SHELL_EXTENSION;
301 entry.location = dll;
302 PopulateModuleInformation(&entry);
303
304 NormalizeModule(&entry);
305 CollapsePath(&entry);
306 enumerated_modules_->push_back(entry);
307
308 ++registration;
309 }
310 }
311
312 void ModuleEnumerator::EnumerateWinsockModule() {
272 // Add to this list the Winsock LSP DLLs. 313 // Add to this list the Winsock LSP DLLs.
273 WinsockLayeredServiceProviderList layered_providers; 314 WinsockLayeredServiceProviderList layered_providers;
274 GetWinsockLayeredServiceProviders(&layered_providers); 315 GetWinsockLayeredServiceProviders(&layered_providers);
275 for (size_t i = 0; i < layered_providers.size(); ++i) { 316 for (size_t i = 0; i < layered_providers.size(); ++i) {
276 Module entry; 317 Module entry;
277 entry.type = WINSOCK_MODULE_REGISTRATION; 318 entry.type = WINSOCK_MODULE_REGISTRATION;
278 entry.status = NOT_MATCHED; 319 entry.status = NOT_MATCHED;
279 entry.normalized = false; 320 entry.normalized = false;
280 entry.location = layered_providers[i].path; 321 entry.location = layered_providers[i].path;
281 entry.description = layered_providers[i].name; 322 entry.description = layered_providers[i].name;
282 entry.recommended_action = NONE; 323 entry.recommended_action = NONE;
283 324
284 wchar_t expanded[MAX_PATH]; 325 wchar_t expanded[MAX_PATH];
285 DWORD size = ExpandEnvironmentStrings( 326 DWORD size = ExpandEnvironmentStrings(
286 entry.location.c_str(), expanded, MAX_PATH); 327 entry.location.c_str(), expanded, MAX_PATH);
287 if (size != 0 && size <= MAX_PATH) { 328 if (size != 0 && size <= MAX_PATH) {
288 entry.digital_signer = 329 entry.digital_signer =
289 GetSubjectNameFromDigitalSignature(FilePath(expanded)); 330 GetSubjectNameFromDigitalSignature(FilePath(expanded));
290 } 331 }
291 entry.version = base::IntToString16(layered_providers[i].version); 332 entry.version = base::IntToString16(layered_providers[i].version);
292 333
293 // Paths have already been collapsed. 334 // Paths have already been collapsed.
294 NormalizeModule(&entry); 335 NormalizeModule(&entry);
295 enumerated_modules_->push_back(entry); 336 enumerated_modules_->push_back(entry);
296 } 337 }
338 }
297 339
298 MatchAgainstBlacklist(); 340 void ModuleEnumerator::PopulateModuleInformation(Module* module) {
341 module->status = NOT_MATCHED;
342 module->normalized = false;
343 module->digital_signer =
344 GetSubjectNameFromDigitalSignature(FilePath(module->location));
345 module->recommended_action = NONE;
346 scoped_ptr<FileVersionInfo> version_info(
347 FileVersionInfo::CreateFileVersionInfo(FilePath(module->location)));
348 if (version_info.get()) {
349 FileVersionInfoWin* version_info_win =
350 static_cast<FileVersionInfoWin*>(version_info.get());
299 351
300 std::sort(enumerated_modules_->begin(), 352 VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info();
301 enumerated_modules_->end(), ModuleSort); 353 if (fixed_file_info) {
302 354 module->description = version_info_win->file_description();
303 // Send a reply back on the UI thread. 355 module->version = version_info_win->file_version();
304 BrowserThread::PostTask( 356 module->product_name = version_info_win->product_name();
305 callback_thread_id_, FROM_HERE, 357 }
306 NewRunnableMethod(this, &ModuleEnumerator::ReportBack)); 358 }
307 } 359 }
308 360
309 void ModuleEnumerator::PreparePathMappings() { 361 void ModuleEnumerator::PreparePathMappings() {
310 path_mapping_.clear(); 362 path_mapping_.clear();
311 363
312 scoped_ptr<base::Environment> environment(base::Environment::Create()); 364 scoped_ptr<base::Environment> environment(base::Environment::Create());
313 std::vector<string16> env_vars; 365 std::vector<string16> env_vars;
314 env_vars.push_back(L"LOCALAPPDATA"); 366 env_vars.push_back(L"LOCALAPPDATA");
315 env_vars.push_back(L"ProgramFiles"); 367 env_vars.push_back(L"ProgramFiles");
316 env_vars.push_back(L"USERPROFILE"); 368 env_vars.push_back(L"USERPROFILE");
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 return NULL; 543 return NULL;
492 } 544 }
493 545
494 ListValue* list = new ListValue(); 546 ListValue* list = new ListValue();
495 547
496 for (ModuleEnumerator::ModulesVector::const_iterator module = 548 for (ModuleEnumerator::ModulesVector::const_iterator module =
497 enumerated_modules_.begin(); 549 enumerated_modules_.begin();
498 module != enumerated_modules_.end(); ++module) { 550 module != enumerated_modules_.end(); ++module) {
499 DictionaryValue* data = new DictionaryValue(); 551 DictionaryValue* data = new DictionaryValue();
500 data->SetInteger("type", module->type); 552 data->SetInteger("type", module->type);
501 data->SetString("type_description", 553 switch (module->type) {
502 (module->type == ModuleEnumerator::WINSOCK_MODULE_REGISTRATION) ? 554 case ModuleEnumerator::SHELL_EXTENSION:
503 ASCIIToWide("Winsock") : ASCIIToWide("")); 555 data->SetString("type_description", ASCIIToWide("Shell Extension"));
556 break;
557 case ModuleEnumerator::WINSOCK_MODULE_REGISTRATION:
558 data->SetString("type_description", ASCIIToWide("Winsock"));
559 break;
560 default:
561 data->SetString("type_description", ASCIIToWide(""));
562 break;
563 }
504 data->SetInteger("status", module->status); 564 data->SetInteger("status", module->status);
505 data->SetString("location", module->location); 565 data->SetString("location", module->location);
506 data->SetString("name", module->name); 566 data->SetString("name", module->name);
507 data->SetString("product_name", module->product_name); 567 data->SetString("product_name", module->product_name);
508 data->SetString("description", module->description); 568 data->SetString("description", module->description);
509 data->SetString("version", module->version.empty() ? ASCIIToWide("") : 569 data->SetString("version", module->version.empty() ? ASCIIToWide("") :
510 l10n_util::GetStringF(IDS_CONFLICTS_CHECK_VERSION_STRING, 570 l10n_util::GetStringF(IDS_CONFLICTS_CHECK_VERSION_STRING,
511 module->version)); 571 module->version));
512 data->SetString("digital_signer", module->digital_signer); 572 data->SetString("digital_signer", module->digital_signer);
513 573
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 GenerateHash(WideToUTF8(module.name), &filename); 670 GenerateHash(WideToUTF8(module.name), &filename);
611 GenerateHash(WideToUTF8(module.location), &location); 671 GenerateHash(WideToUTF8(module.location), &location);
612 GenerateHash(WideToUTF8(module.description), &description); 672 GenerateHash(WideToUTF8(module.description), &description);
613 GenerateHash(WideToUTF8(module.digital_signer), &signer); 673 GenerateHash(WideToUTF8(module.digital_signer), &signer);
614 674
615 string16 url = l10n_util::GetStringF(IDS_HELP_CENTER_VIEW_CONFLICTS, 675 string16 url = l10n_util::GetStringF(IDS_HELP_CENTER_VIEW_CONFLICTS,
616 ASCIIToWide(filename), ASCIIToWide(location), 676 ASCIIToWide(filename), ASCIIToWide(location),
617 ASCIIToWide(description), ASCIIToWide(signer)); 677 ASCIIToWide(description), ASCIIToWide(signer));
618 return GURL(WideToUTF8(url)); 678 return GURL(WideToUTF8(url));
619 } 679 }
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