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
ParseRegistry(HKEY key,ATL::CString print_name)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
TestRegAccess(HKEY key,ATL::CString name,ATL::CString print_name)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