123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #include "il2cpp-config.h"
- #if IL2CPP_TARGET_WINDOWS
- #include "WindowsHeaders.h"
- #undef FindFirstFile
- #undef FindNextFile
- #include "os/Directory.h"
- #include "os/ErrorCodes.h"
- #include "utils/StringUtils.h"
- #include "utils/PathUtils.h"
- #if IL2CPP_TARGET_WINRT
- #include "os/BrokeredFileSystem.h"
- #endif
- static inline int DirectoryWin32ErrorToErrorCode(DWORD win32ErrorCode)
- {
- return win32ErrorCode;
- }
- using namespace il2cpp::utils::PathUtils;
- namespace il2cpp
- {
- namespace os
- {
- std::string Directory::GetCurrent(int *error)
- {
- UTF16String buf;
- int len, res_len;
- len = MAX_PATH + 1;
- buf.resize(len, 0);
- *error = ERROR_SUCCESS;
- res_len = ::GetCurrentDirectory(len, (LPWSTR)buf.c_str());
- if (res_len > len) /*buf is too small.*/
- {
- int old_res_len = res_len;
- buf.resize(res_len, 0);
- res_len = ::GetCurrentDirectory(res_len, (LPWSTR)buf.c_str()) == old_res_len;
- }
- std::string directory;
- if (res_len)
- {
- len = 0;
- while (buf[len])
- ++len;
- directory = il2cpp::utils::StringUtils::Utf16ToUtf8(buf.c_str());
- }
- else
- {
- *error = DirectoryWin32ErrorToErrorCode(::GetLastError());
- }
- return directory;
- }
- bool Directory::SetCurrent(const std::string& path, int* error)
- {
- *error = kErrorCodeSuccess;
- const UTF16String utf16Path(il2cpp::utils::StringUtils::Utf8ToUtf16(path.c_str()));
- if (::SetCurrentDirectory((LPWSTR)utf16Path.c_str()))
- return true;
- *error = DirectoryWin32ErrorToErrorCode(::GetLastError());
- return false;
- }
- bool Directory::Create(const std::string& path, int *error)
- {
- *error = kErrorCodeSuccess;
- const UTF16String utf16Path(il2cpp::utils::StringUtils::Utf8ToUtf16(path.c_str()));
- if (::CreateDirectory((LPWSTR)utf16Path.c_str(), NULL))
- return true;
- auto lastError = ::GetLastError();
- #if IL2CPP_TARGET_WINRT
- if (lastError == ERROR_ACCESS_DENIED)
- {
- *error = BrokeredFileSystem::CreateDirectoryW(utf16Path);
- return *error == kErrorCodeSuccess;
- }
- #endif
- *error = DirectoryWin32ErrorToErrorCode(lastError);
- return false;
- }
- bool Directory::Remove(const std::string& path, int *error)
- {
- *error = kErrorCodeSuccess;
- const UTF16String utf16Path(il2cpp::utils::StringUtils::Utf8ToUtf16(path.c_str()));
- if (::RemoveDirectory((LPWSTR)utf16Path.c_str()))
- return true;
- auto lastError = ::GetLastError();
- #if IL2CPP_TARGET_WINRT
- if (lastError == ERROR_ACCESS_DENIED)
- {
- *error = BrokeredFileSystem::RemoveDirectoryW(utf16Path);
- return *error == kErrorCodeSuccess;
- }
- #endif
- *error = DirectoryWin32ErrorToErrorCode(lastError);
- return false;
- }
- std::set<std::string> Directory::GetFileSystemEntries(const std::string& path, const std::string& pathWithPattern, int32_t attrs, int32_t mask, int* error)
- {
- *error = kErrorCodeSuccess;
- std::set<std::string> files;
- WIN32_FIND_DATA ffd;
- const UTF16String utf16Path(il2cpp::utils::StringUtils::Utf8ToUtf16(pathWithPattern));
- HANDLE handle = ::FindFirstFileExW((LPCWSTR)utf16Path.c_str(), FindExInfoStandard, &ffd, FindExSearchNameMatch, NULL, 0);
- if (INVALID_HANDLE_VALUE == handle)
- {
- auto lastError = ::GetLastError();
- #if IL2CPP_TARGET_WINRT
- if (lastError == ERROR_ACCESS_DENIED)
- return BrokeredFileSystem::GetFileSystemEntries(utils::StringUtils::Utf8ToUtf16(path), utf16Path, attrs, mask, error);
- #endif
- // Following the Mono implementation, do not treat a directory with no files as an error.
- int errorCode = DirectoryWin32ErrorToErrorCode(lastError);
- if (errorCode != ERROR_FILE_NOT_FOUND)
- *error = errorCode;
- return files;
- }
- do
- {
- const std::string fileName(il2cpp::utils::StringUtils::Utf16ToUtf8(ffd.cFileName));
- if ((fileName.length() == 1 && fileName.at(0) == '.') ||
- (fileName.length() == 2 && fileName.at(0) == '.' && fileName.at(1) == '.'))
- continue;
- if ((ffd.dwFileAttributes & mask) == attrs)
- {
- files.insert(Combine(path, fileName));
- }
- }
- while (::FindNextFileW(handle, &ffd) != 0);
- ::FindClose(handle);
- return files;
- }
- Directory::FindHandle::FindHandle(const utils::StringView<Il2CppNativeChar>& searchPathWithPattern) :
- osHandle(INVALID_HANDLE_VALUE),
- handleFlags(os::kNoFindHandleFlags),
- directoryPath(il2cpp::utils::PathUtils::DirectoryName(searchPathWithPattern)),
- pattern(il2cpp::utils::PathUtils::Basename(searchPathWithPattern))
- {
- }
- Directory::FindHandle::~FindHandle()
- {
- IL2CPP_ASSERT(osHandle == INVALID_HANDLE_VALUE);
- }
- int32_t Directory::FindHandle::CloseOSHandle()
- {
- int32_t result = os::kErrorCodeSuccess;
- if (osHandle != INVALID_HANDLE_VALUE)
- {
- #if IL2CPP_TARGET_WINRT
- if (handleFlags & kUseBrokeredFileSystem)
- {
- result = BrokeredFileSystem::FindClose(osHandle);
- }
- else
- #endif
- {
- result = ::FindClose(osHandle);
- }
- osHandle = INVALID_HANDLE_VALUE;
- }
- return result;
- }
- os::ErrorCode Directory::FindFirstFile(FindHandle* findHandle, const utils::StringView<Il2CppNativeChar>& searchPathWithPattern, Il2CppNativeString* resultFileName, int32_t* resultAttributes)
- {
- WIN32_FIND_DATA findData;
- HANDLE handle = FindFirstFileExW(searchPathWithPattern.Str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0);
- if (handle != INVALID_HANDLE_VALUE)
- {
- findHandle->SetOSHandle(handle);
- *resultFileName = findData.cFileName;
- *resultAttributes = findData.dwFileAttributes;
- return os::kErrorCodeSuccess;
- }
- else
- {
- auto lastError = GetLastError();
- #if IL2CPP_TARGET_WINRT
- if (lastError == ERROR_ACCESS_DENIED)
- return BrokeredFileSystem::FindFirstFileW(findHandle, searchPathWithPattern, resultFileName, resultAttributes);
- #endif
- return static_cast<os::ErrorCode>(lastError);
- }
- }
- os::ErrorCode Directory::FindNextFile(FindHandle* findHandle, Il2CppNativeString* resultFileName, int32_t* resultAttributes)
- {
- #if IL2CPP_TARGET_WINRT
- if (findHandle->handleFlags & kUseBrokeredFileSystem)
- return BrokeredFileSystem::FindNextFileW(findHandle, resultFileName, resultAttributes);
- #endif
- WIN32_FIND_DATA findData;
- if (FindNextFileW(findHandle->osHandle, &findData) == FALSE)
- return static_cast<os::ErrorCode>(GetLastError());
- *resultFileName = findData.cFileName;
- *resultAttributes = findData.dwFileAttributes;
- return os::kErrorCodeSuccess;
- }
- int32_t Directory::CloseOSFindHandleDirectly(intptr_t osHandle)
- {
- return ::FindClose((HANDLE)osHandle);
- }
- }
- }
- #endif
|