Home | History | Annotate | Download | only in profiles
      1 // Copyright 2013 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 "chrome/browser/profiles/file_path_verifier_win.h"
      6 
      7 #include <windows.h>
      8 
      9 #include "base/file_util.h"
     10 #include "base/files/file_path.h"
     11 #include "base/metrics/histogram.h"
     12 
     13 namespace {
     14 
     15 // This enum is used in UMA histograms and should never be re-ordered.
     16 enum FileVerificationResult {
     17   FILE_VERIFICATION_SUCCESS,
     18   FILE_VERIFICATION_FILE_NOT_FOUND,
     19   FILE_VERIFICATION_INTERNAL_ERROR,
     20   FILE_VERIFICATION_FAILED_UNKNOWN,
     21   FILE_VERIFICATION_FAILED_SAMEBASE,
     22   FILE_VERIFICATION_FAILED_SAMEDIR,
     23   NUM_FILE_VERIFICATION_RESULTS
     24 };
     25 
     26 // Returns a FileVerificationResult based on the state of |file| on disk.
     27 FileVerificationResult VerifyFileAtPath(const base::FilePath& file) {
     28   FileVerificationResult file_verification_result =
     29       FILE_VERIFICATION_FAILED_UNKNOWN;
     30   base::FilePath normalized_path;
     31   if (!base::NormalizeFilePath(file, &normalized_path)) {
     32     if (::GetLastError() == ERROR_FILE_NOT_FOUND)
     33       file_verification_result = FILE_VERIFICATION_FILE_NOT_FOUND;
     34     else
     35       file_verification_result = FILE_VERIFICATION_INTERNAL_ERROR;
     36   } else {
     37     internal::PathComparisonReason path_comparison_reason =
     38         internal::ComparePathsIgnoreCase(file, normalized_path);
     39     switch (path_comparison_reason) {
     40       case internal::PATH_COMPARISON_EQUAL:
     41         file_verification_result = FILE_VERIFICATION_SUCCESS;
     42         break;
     43       case internal::PATH_COMPARISON_FAILED_SAMEBASE:
     44         file_verification_result = FILE_VERIFICATION_FAILED_SAMEBASE;
     45         break;
     46       case internal::PATH_COMPARISON_FAILED_SAMEDIR:
     47         file_verification_result = FILE_VERIFICATION_FAILED_SAMEDIR;
     48         break;
     49     }
     50   }
     51   return file_verification_result;
     52 }
     53 
     54 }  // namespace
     55 
     56 namespace internal {
     57 
     58 PathComparisonReason ComparePathsIgnoreCase(const base::FilePath& path1,
     59                                             const base::FilePath& path2) {
     60   PathComparisonReason reason = PATH_COMPARISON_FAILED_UNKNOWN;
     61 
     62   if (base::FilePath::CompareEqualIgnoreCase(path1.value(), path2.value())) {
     63     reason = PATH_COMPARISON_EQUAL;
     64   } else if (base::FilePath::CompareEqualIgnoreCase(path1.BaseName().value(),
     65                                                     path2.BaseName().value())) {
     66     reason = PATH_COMPARISON_FAILED_SAMEBASE;
     67   } else if (base::FilePath::CompareEqualIgnoreCase(path1.DirName().value(),
     68                                                     path2.DirName().value())) {
     69     reason = PATH_COMPARISON_FAILED_SAMEDIR;
     70   }
     71 
     72   return reason;
     73 }
     74 
     75 }  // namespace internal
     76 
     77 void VerifyPreferencesFile(const base::FilePath& pref_file_path) {
     78   FileVerificationResult file_verification_result =
     79       VerifyFileAtPath(pref_file_path);
     80   UMA_HISTOGRAM_ENUMERATION("Stability.FileAtPath.Preferences",
     81                             file_verification_result,
     82                             NUM_FILE_VERIFICATION_RESULTS);
     83 }
     84