Home | History | Annotate | Download | only in finder
      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 
      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 
     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