• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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