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