aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarlson2k <k2k@narod.ru>2014-06-07 22:00:45 +0400
committerKarlson2k <k2k@narod.ru>2014-06-08 11:37:41 +0400
commitf5ea133bb98a22f982bf1dd964bb7b167f0383d6 (patch)
tree949a4a9800376994d5f258268632c46992b324bb
parent1d00ba40fe00a8074024f4d12c15de29774d83d1 (diff)
[win32] Implement class CWin32Directory
-rw-r--r--project/VS2010Express/XBMC.vcxproj2
-rw-r--r--project/VS2010Express/XBMC.vcxproj.filters11
-rw-r--r--xbmc/filesystem/win32/Win32Directory.cpp184
-rw-r--r--xbmc/filesystem/win32/Win32Directory.h37
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);
+ };
+}