1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "sandbox/win/src/restricted_token.h" 6 #include "sandbox/win/src/restricted_token_utils.h" 7 #include "sandbox/win/tools/finder/finder.h" 8 9 DWORD Finder::ParseRegistry(HKEY key, ATL::CString print_name) { 10 DWORD index = 0; 11 DWORD name_size = 2048; 12 wchar_t buffer[2048] = {0}; 13 // TODO(nsylvain): Don't hardcode 2048. Get the key len by calling the 14 // function. 15 LONG err_code = ::RegEnumKey(key, index, buffer, name_size); 16 while (ERROR_SUCCESS == err_code) { 17 ATL::CString name_complete = print_name + buffer + L"\\"; 18 TestRegAccess(key, buffer, name_complete); 19 20 // Call the function recursively to parse all subkeys 21 HKEY key_to_parse; 22 err_code = ::RegOpenKeyEx(key, buffer, 0, KEY_ENUMERATE_SUB_KEYS, 23 &key_to_parse); 24 if (ERROR_SUCCESS == err_code) { 25 ParseRegistry(key_to_parse, name_complete); 26 ::RegCloseKey(key_to_parse); 27 } else { 28 registry_stats_[BROKEN]++; 29 Output(REG_ERR, err_code, name_complete); 30 } 31 32 index++; 33 err_code = ::RegEnumKey(key, index, buffer, name_size); 34 } 35 36 if (ERROR_NO_MORE_ITEMS != err_code) { 37 registry_stats_[BROKEN]++; 38 Output(REG_ERR, err_code, print_name); 39 } 40 41 return ERROR_SUCCESS; 42 } 43 44 DWORD Finder::TestRegAccess(HKEY key, ATL::CString name, 45 ATL::CString print_name) { 46 Impersonater impersonate(token_handle_); 47 48 registry_stats_[PARSE]++; 49 50 HKEY key_res; 51 LONG err_code = 0; 52 53 if (access_type_ & kTestForAll) { 54 err_code = ::RegOpenKeyEx(key, name, 0, GENERIC_ALL, &key_res); 55 if (ERROR_SUCCESS == err_code) { 56 registry_stats_[ALL]++; 57 Output(REG, L"R/W", print_name); 58 ::RegCloseKey(key_res); 59 return GENERIC_ALL; 60 } else if (err_code != ERROR_ACCESS_DENIED) { 61 Output(REG_ERR, err_code, print_name); 62 registry_stats_[BROKEN]++; 63 } 64 } 65 66 if (access_type_ & kTestForWrite) { 67 err_code = ::RegOpenKeyEx(key, name, 0, GENERIC_WRITE, &key_res); 68 if (ERROR_SUCCESS == err_code) { 69 registry_stats_[WRITE]++; 70 Output(REG, L"W", print_name); 71 ::RegCloseKey(key_res); 72 return GENERIC_WRITE; 73 } else if (err_code != ERROR_ACCESS_DENIED) { 74 Output(REG_ERR, err_code, print_name); 75 registry_stats_[BROKEN]++; 76 } 77 } 78 79 if (access_type_ & kTestForRead) { 80 err_code = ::RegOpenKeyEx(key, name, 0, GENERIC_READ, &key_res); 81 if (ERROR_SUCCESS == err_code) { 82 registry_stats_[READ]++; 83 Output(REG, L"R", print_name); 84 ::RegCloseKey(key_res); 85 return GENERIC_READ; 86 } else if (err_code != ERROR_ACCESS_DENIED) { 87 Output(REG_ERR, err_code, print_name); 88 registry_stats_[BROKEN]++; 89 } 90 } 91 92 return 0; 93 } 94