diff options
author | Karlson2k <k2k@narod.ru> | 2014-06-07 22:00:45 +0400 |
---|---|---|
committer | Karlson2k <k2k@narod.ru> | 2014-06-08 11:37:41 +0400 |
commit | f5ea133bb98a22f982bf1dd964bb7b167f0383d6 (patch) | |
tree | 949a4a9800376994d5f258268632c46992b324bb | |
parent | 1d00ba40fe00a8074024f4d12c15de29774d83d1 (diff) |
[win32] Implement class CWin32Directory
-rw-r--r-- | project/VS2010Express/XBMC.vcxproj | 2 | ||||
-rw-r--r-- | project/VS2010Express/XBMC.vcxproj.filters | 11 | ||||
-rw-r--r-- | xbmc/filesystem/win32/Win32Directory.cpp | 184 | ||||
-rw-r--r-- | xbmc/filesystem/win32/Win32Directory.h | 37 |
4 files changed, 233 insertions, 1 deletions
diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 055722f9a3..175af49e33 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -387,6 +387,7 @@ <ClCompile Include="..\..\xbmc\filesystem\UPnPFile.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\VideoDatabaseDirectory.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\VideoDatabaseDirectory\DirectoryNodeGrouped.cpp" /> + <ClCompile Include="..\..\xbmc\filesystem\win32\Win32Directory.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\windows\WINFileSMB.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.cpp" /> <ClCompile Include="..\..\xbmc\filesystem\VirtualDirectory.cpp" /> @@ -847,6 +848,7 @@ <ClInclude Include="..\..\xbmc\filesystem\ImageFile.h" /> <ClInclude Include="..\..\xbmc\filesystem\MusicDatabaseDirectory\DirectoryNodeGrouped.h" /> <ClInclude Include="..\..\xbmc\filesystem\VideoDatabaseDirectory\DirectoryNodeGrouped.h" /> + <ClInclude Include="..\..\xbmc\filesystem\win32\Win32Directory.h" /> <ClInclude Include="..\..\xbmc\filesystem\windows\WINFileSMB.h" /> <ClInclude Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.h" /> <CustomBuild Include="..\..\xbmc\GitRevision.h"> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index 2d2c5dc16a..600c47c98f 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -316,6 +316,9 @@ <Filter Include="media"> <UniqueIdentifier>{fe89da97-8cd1-4ba3-8ef2-ae4ae5498d59}</UniqueIdentifier> </Filter> + <Filter Include="filesystem\win32"> + <UniqueIdentifier>{901e970d-b3b4-463a-93ab-9af30c6a1139}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\xbmc\win32\pch.cpp"> @@ -3074,6 +3077,9 @@ <ClCompile Include="..\..\xbmc\settings\SettingUtils.cpp"> <Filter>settings</Filter> </ClCompile> + <ClCompile Include="..\..\xbmc\filesystem\win32\Win32Directory.cpp"> + <Filter>filesystem\win32</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\xbmc\win32\pch.h"> @@ -6030,6 +6036,9 @@ <ClInclude Include="..\..\xbmc\settings\SettingUtils.h"> <Filter>settings</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\filesystem\win32\Win32Directory.h"> + <Filter>filesystem\win32</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc"> @@ -6074,4 +6083,4 @@ <Filter>interfaces\swig</Filter> </None> </ItemGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/xbmc/filesystem/win32/Win32Directory.cpp b/xbmc/filesystem/win32/Win32Directory.cpp new file mode 100644 index 0000000000..27e21640c8 --- /dev/null +++ b/xbmc/filesystem/win32/Win32Directory.cpp @@ -0,0 +1,184 @@ +/* +* Copyright (C) 2014 Team XBMC +* http://xbmc.org +* +* This Program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This Program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with XBMC; see the file COPYING. If not, see +* <http://www.gnu.org/licenses/>. +* +*/ + +#ifdef TARGET_WINDOWS +#include "Win32Directory.h" +#include "FileItem.h" +#include "win32/WIN32Util.h" +#include "utils/SystemInfo.h" +#include "utils/CharsetConverter.h" + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif // WIN32_LEAN_AND_MEAN +#include <Windows.h> + +using namespace XFILE; + +// check for empty string, remove trailing slash if any, convert to win32 form +inline static std::wstring prepareWin32DirectoryName(const std::string& strPath) +{ + if (strPath.empty()) + return std::wstring(); // empty string + + std::wstring nameW(CWIN32Util::ConvertPathToWin32Form(strPath)); + if (!nameW.empty() && nameW.back() == L'\\') + nameW.pop_back(); // remove slash at the end if any + + return nameW; +} + +// check for NULL and empty string, remove trailing slash if any, convert to win32 form +inline static std::wstring prepareWin32DirectoryName(const char* strPath) +{ + if (strPath == NULL) + return std::wstring(); // empty string + + return prepareWin32DirectoryName(std::string(strPath)); +} + +CWin32Directory::CWin32Directory(void) +{} + +CWin32Directory::~CWin32Directory(void) +{} + +bool CWin32Directory::GetDirectory(const CStdString& strPath, CFileItemList &items) +{ + items.Clear(); + if (strPath.empty()) + return false; + + std::string pathWithSlash(strPath); + if (pathWithSlash.back() != '\\') + pathWithSlash.push_back('\\'); + + std::wstring searchMask(CWIN32Util::ConvertPathToWin32Form(pathWithSlash)); + if (searchMask.empty()) + return false; + + // TODO: support m_strFileMask, require rewrite of internal caching + searchMask += L'*'; + + HANDLE hSearch; + WIN32_FIND_DATAW findData = {}; + + if (g_sysinfo.IsWindowsVersionAtLeast(CSysInfo::WindowsVersionWin7)) + hSearch = FindFirstFileExW(searchMask.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH); + else + hSearch = FindFirstFileExW(searchMask.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); + + if (hSearch == INVALID_HANDLE_VALUE) + return Exists(strPath); // return true if directory exist and empty + + do + { + std::wstring itemNameW(findData.cFileName); + if (itemNameW == L"." || itemNameW == L"..") + continue; + + std::string itemName; + g_charsetConverter.wToUTF8(itemNameW, itemName); + if (itemName.empty()) + continue; + + CFileItemPtr pItem(new CFileItem(itemName)); + + pItem->m_bIsFolder = ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + if (pItem->m_bIsFolder) + pItem->SetPath(pathWithSlash + itemName + '\\'); + else + pItem->SetPath(pathWithSlash + itemName); + + if ((findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != 0 + || itemName.front() == '.') // mark files starting from dot as hidden + pItem->SetProperty("file:hidden", true); + + // calculation of size and date costs a little on win32 + // so DIR_FLAG_NO_FILE_INFO flag is ignored + FILETIME localTime; + if (FileTimeToLocalFileTime(&findData.ftLastWriteTime, &localTime) == TRUE) + pItem->m_dateTime = localTime; + else + pItem->m_dateTime = 0; + + if (!pItem->m_bIsFolder) + pItem->m_dwSize = (__int64(findData.nFileSizeHigh) << 32) + findData.nFileSizeLow; + + items.Add(pItem); + } while (FindNextFileW(hSearch, &findData)); + + FindClose(hSearch); + + return true; +} + +bool CWin32Directory::Create(const char* strPath) +{ + std::wstring nameW(prepareWin32DirectoryName(strPath)); + if (nameW.empty()) + return false; + + if (!CreateDirectoryW(nameW.c_str(), NULL)) + { + if (GetLastError() == ERROR_ALREADY_EXISTS) + return Exists(strPath); // is it file or directory? + else + return false; + } + + // if directory name starts from dot, make it hidden + const size_t lastSlashPos = nameW.rfind(L'\\'); + if (lastSlashPos < nameW.length() - 1 && nameW[lastSlashPos + 1] == L'.') + { + DWORD dirAttrs = GetFileAttributesW(nameW.c_str()); + if (dirAttrs != INVALID_FILE_ATTRIBUTES && SetFileAttributesW(nameW.c_str(), dirAttrs | FILE_ATTRIBUTE_HIDDEN)) + return true; + } + + return true; +} + +bool CWin32Directory::Exists(const char* strPath) +{ + std::wstring nameW(prepareWin32DirectoryName(strPath)); + if (nameW.empty()) + return false; + + DWORD fileAttrs = GetFileAttributesW(nameW.c_str()); + if (fileAttrs == INVALID_FILE_ATTRIBUTES || (fileAttrs & FILE_ATTRIBUTE_DIRECTORY) == 0) + return false; + + return true; +} + +bool CWin32Directory::Remove(const char* strPath) +{ + std::wstring nameW(prepareWin32DirectoryName(strPath)); + if (nameW.empty()) + return false; + + if (RemoveDirectoryW(nameW.c_str())) + return true; + + return !Exists(strPath); +} + +#endif // TARGET_WINDOWS diff --git a/xbmc/filesystem/win32/Win32Directory.h b/xbmc/filesystem/win32/Win32Directory.h new file mode 100644 index 0000000000..fdbb0b55ea --- /dev/null +++ b/xbmc/filesystem/win32/Win32Directory.h @@ -0,0 +1,37 @@ +#pragma once +/* +* Copyright (C) 2014 Team XBMC +* http://xbmc.org +* +* This Program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This Program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with XBMC; see the file COPYING. If not, see +* <http://www.gnu.org/licenses/>. +* +*/ + +#include "filesystem/IDirectory.h" + +namespace XFILE +{ + + class CWin32Directory : public IDirectory + { + public: + CWin32Directory(void); + virtual ~CWin32Directory(void); + virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items); + virtual bool Create(const char* strPath); + virtual bool Exists(const char* strPath); + virtual bool Remove(const char* strPath); + }; +} |