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