• 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 
ParseFileSystem(ATL::CString directory)9 DWORD Finder::ParseFileSystem(ATL::CString directory) {
10   WIN32_FIND_DATA find_data;
11   HANDLE find;
12 
13   //Search for items in the directory.
14   ATL::CString name_to_search = directory + L"\\*";
15   find = ::FindFirstFile(name_to_search, &find_data);
16   if (INVALID_HANDLE_VALUE == find) {
17     DWORD error = ::GetLastError();
18     Output(FS_ERR, error, directory);
19     filesystem_stats_[BROKEN]++;
20     return error;
21   }
22 
23   // parse all files or folders.
24   do {
25     if (_tcscmp(find_data.cFileName, L".") == 0 ||
26         _tcscmp(find_data.cFileName, L"..") == 0)
27       continue;
28 
29     ATL::CString complete_name = directory + L"\\" + find_data.cFileName;
30     TestFileAccess(complete_name);
31 
32     // Call recursively the function if the path found is a directory.
33     if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
34       ParseFileSystem(complete_name);
35     }
36   } while (::FindNextFile(find, &find_data) != 0);
37 
38   DWORD err_code = ::GetLastError();
39   ::FindClose(find);
40 
41   if (ERROR_NO_MORE_FILES != err_code) {
42     Output(FS_ERR, err_code, directory);
43     filesystem_stats_[BROKEN]++;
44     return err_code;
45   }
46 
47   return ERROR_SUCCESS;
48 }
49 
TestFileAccess(ATL::CString name)50 DWORD Finder::TestFileAccess(ATL::CString name) {
51   Impersonater impersonate(token_handle_);
52 
53   filesystem_stats_[PARSE]++;
54 
55   HANDLE file;
56   if (access_type_ & kTestForAll) {
57     file = ::CreateFile(name.GetBuffer(),
58                         GENERIC_ALL,
59                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
60                         NULL,
61                         OPEN_EXISTING,
62                         FILE_ATTRIBUTE_NORMAL,
63                         NULL);
64 
65     if (file != INVALID_HANDLE_VALUE) {
66       filesystem_stats_[ALL]++;
67       Output(FS, L"R/W", name.GetBuffer());
68       ::CloseHandle(file);
69       return GENERIC_ALL;
70     } else if (::GetLastError() != ERROR_ACCESS_DENIED) {
71       Output(FS_ERR, GetLastError(), name);
72       filesystem_stats_[BROKEN]++;
73     }
74   }
75 
76   if (access_type_ & kTestForWrite) {
77     file = ::CreateFile(name.GetBuffer(),
78                         GENERIC_WRITE,
79                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
80                         NULL,
81                         OPEN_EXISTING,
82                         FILE_ATTRIBUTE_NORMAL,
83                         NULL);
84 
85     if (file != INVALID_HANDLE_VALUE) {
86       filesystem_stats_[WRITE]++;
87       Output(FS, L"W", name);
88       ::CloseHandle(file);
89       return GENERIC_WRITE;
90     } else if (::GetLastError() != ERROR_ACCESS_DENIED) {
91       Output(FS_ERR, ::GetLastError(), name);
92       filesystem_stats_[BROKEN]++;
93     }
94   }
95 
96   if (access_type_ & kTestForRead) {
97     file = ::CreateFile(name.GetBuffer(),
98                         GENERIC_READ,
99                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
100                         NULL,
101                         OPEN_EXISTING,
102                         FILE_ATTRIBUTE_NORMAL,
103                         NULL);
104 
105     if (file != INVALID_HANDLE_VALUE) {
106       filesystem_stats_[READ]++;
107       Output(FS, L"R", name);
108       ::CloseHandle(file);
109       return GENERIC_READ;
110     } else if (::GetLastError() != ERROR_ACCESS_DENIED) {
111       Output(FS_ERR, GetLastError(), name);
112       filesystem_stats_[BROKEN]++;
113     }
114   }
115 
116   return 0;
117 }
118