blob: 7375b86d562c8206a39c5aea62f94960cc7b0123 [file] [log] [blame]
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sandbox/src/restricted_token.h"
#include "sandbox/src/restricted_token_utils.h"
#include "sandbox/tools/finder/finder.h"
DWORD Finder::ParseFileSystem(ATL::CString directory) {
WIN32_FIND_DATA find_data;
HANDLE find;
//Search for items in the directory.
ATL::CString name_to_search = directory + L"\\*";
find = ::FindFirstFile(name_to_search, &find_data);
if (INVALID_HANDLE_VALUE == find) {
DWORD error = ::GetLastError();
Output(FS_ERR, error, directory);
filesystem_stats_[BROKEN]++;
return error;
}
// parse all files or folders.
do {
if (_tcscmp(find_data.cFileName, L".") == 0 ||
_tcscmp(find_data.cFileName, L"..") == 0)
continue;
ATL::CString complete_name = directory + L"\\" + find_data.cFileName;
TestFileAccess(complete_name);
// Call recursively the function if the path found is a directory.
if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
ParseFileSystem(complete_name);
}
} while (::FindNextFile(find, &find_data) != 0);
DWORD err_code = ::GetLastError();
::FindClose(find);
if (ERROR_NO_MORE_FILES != err_code) {
Output(FS_ERR, err_code, directory);
filesystem_stats_[BROKEN]++;
return err_code;
}
return ERROR_SUCCESS;
}
DWORD Finder::TestFileAccess(ATL::CString name) {
Impersonater impersonate(token_handle_);
filesystem_stats_[PARSE]++;
HANDLE file;
if (access_type_ & kTestForAll) {
file = ::CreateFile(name.GetBuffer(),
GENERIC_ALL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (file != INVALID_HANDLE_VALUE) {
filesystem_stats_[ALL]++;
Output(FS, L"R/W", name.GetBuffer());
::CloseHandle(file);
return GENERIC_ALL;
} else if (::GetLastError() != ERROR_ACCESS_DENIED) {
Output(FS_ERR, GetLastError(), name);
filesystem_stats_[BROKEN]++;
}
}
if (access_type_ & kTestForWrite) {
file = ::CreateFile(name.GetBuffer(),
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (file != INVALID_HANDLE_VALUE) {
filesystem_stats_[WRITE]++;
Output(FS, L"W", name);
::CloseHandle(file);
return GENERIC_WRITE;
} else if (::GetLastError() != ERROR_ACCESS_DENIED) {
Output(FS_ERR, ::GetLastError(), name);
filesystem_stats_[BROKEN]++;
}
}
if (access_type_ & kTestForRead) {
file = ::CreateFile(name.GetBuffer(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (file != INVALID_HANDLE_VALUE) {
filesystem_stats_[READ]++;
Output(FS, L"R", name);
::CloseHandle(file);
return GENERIC_READ;
} else if (::GetLastError() != ERROR_ACCESS_DENIED) {
Output(FS_ERR, GetLastError(), name);
filesystem_stats_[BROKEN]++;
}
}
return 0;
}