Home | History | Annotate | Download | only in finder
      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