[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / filesystem / HDDirectory.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "HDDirectory.h"
22 #include "Util.h"
23 #include "iso9660.h"
24 #include "URL.h"
25 #include "FileItem.h"
26 #include "utils/AutoPtrHandle.h"
27 #include "utils/AliasShortcutUtils.h"
28 #include "utils/URIUtils.h"
29
30 #ifndef _LINUX
31 #include "utils/CharsetConverter.h"
32 #endif
33
34 #ifndef INVALID_FILE_ATTRIBUTES
35 #define INVALID_FILE_ATTRIBUTES ((DWORD) -1)
36 #endif
37
38 #ifdef _WIN32
39 typedef WIN32_FIND_DATAW LOCAL_WIN32_FIND_DATA;
40 #define LocalFindFirstFile FindFirstFileW
41 #define LocalFindNextFile FindNextFileW
42 #else
43 typedef WIN32_FIND_DATA LOCAL_WIN32_FIND_DATA;
44 #define LocalFindFirstFile FindFirstFile
45 #define LocalFindNextFile FindNextFile
46 #endif
47
48 using namespace AUTOPTR;
49 using namespace XFILE;
50
51 CHDDirectory::CHDDirectory(void)
52 {}
53
54 CHDDirectory::~CHDDirectory(void)
55 {}
56
57 bool CHDDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items)
58 {
59   LOCAL_WIN32_FIND_DATA wfd;
60
61   CStdString strPath=strPath1;
62
63   if (IsAliasShortcut(strPath))
64     TranslateAliasShortcut(strPath);
65
66   CStdString strRoot = strPath;
67   CURL url(strPath);
68
69   memset(&wfd, 0, sizeof(wfd));
70   URIUtils::AddSlashAtEnd(strRoot);
71 #ifdef _WIN32
72   strRoot.Replace("/", "\\");
73 #endif
74   if (URIUtils::IsDVD(strRoot) && m_isoReader.IsScanned())
75   {
76     // Reset iso reader and remount or
77     // we can't access the dvd-rom
78     m_isoReader.Reset();
79   }
80
81 #ifdef _WIN32
82   CStdStringW strSearchMask;
83   g_charsetConverter.utf8ToW(strRoot, strSearchMask, false);
84   strSearchMask += "*.*";
85 #else
86   CStdString strSearchMask = strRoot;
87 #endif
88
89   FILETIME localTime;
90   CAutoPtrFind hFind ( LocalFindFirstFile(strSearchMask.c_str(), &wfd));
91
92   // on error, check if path exists at all, this will return true if empty folder
93   if (!hFind.isValid())
94       return Exists(strPath1);
95
96   if (hFind.isValid())
97   {
98     do
99     {
100       if (wfd.cFileName[0] != 0)
101       {
102         CStdString strLabel;
103 #ifdef _WIN32
104         g_charsetConverter.wToUTF8(wfd.cFileName,strLabel);
105 #else
106         strLabel = wfd.cFileName;
107 #endif
108         if ( (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
109         {
110           if (strLabel != "." && strLabel != "..")
111           {
112             CFileItemPtr pItem(new CFileItem(strLabel));
113             CStdString itemPath = strRoot + strLabel;
114             URIUtils::AddSlashAtEnd(itemPath);
115             pItem->SetPath(itemPath);
116             pItem->m_bIsFolder = true;
117             FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime);
118             pItem->m_dateTime=localTime;
119
120             if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
121               pItem->SetProperty("file:hidden", true);
122             items.Add(pItem);
123           }
124         }
125         else
126         {
127           CFileItemPtr pItem(new CFileItem(strLabel));
128           pItem->SetPath(strRoot + strLabel);
129           pItem->m_bIsFolder = false;
130           pItem->m_dwSize = CUtil::ToInt64(wfd.nFileSizeHigh, wfd.nFileSizeLow);
131           FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime);
132           pItem->m_dateTime=localTime;
133
134           if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
135             pItem->SetProperty("file:hidden", true);
136
137           items.Add(pItem);
138         }
139       }
140     }
141     while (LocalFindNextFile((HANDLE)hFind, &wfd));
142   }
143   return true;
144 }
145
146 bool CHDDirectory::Create(const char* strPath)
147 {
148   CStdString strPath1 = strPath;
149   URIUtils::AddSlashAtEnd(strPath1);
150
151 #ifdef _WIN32
152   if (strPath1.size() == 3 && strPath1[1] == ':')
153     return Exists(strPath);  // A drive - we can't "create" a drive
154   CStdStringW strWPath1;
155   g_charsetConverter.utf8ToW(strPath1, strWPath1, false);
156   if(::CreateDirectoryW(strWPath1, NULL))
157 #else
158   if(::CreateDirectory(strPath1.c_str(), NULL))
159 #endif
160     return true;
161   else if(GetLastError() == ERROR_ALREADY_EXISTS)
162     return true;
163
164   return false;
165 }
166
167 bool CHDDirectory::Remove(const char* strPath)
168 {
169 #ifdef _WIN32
170   CStdStringW strWPath;
171   g_charsetConverter.utf8ToW(strPath, strWPath, false);
172   return (::RemoveDirectoryW(strWPath) || GetLastError() == ERROR_PATH_NOT_FOUND) ? true : false;
173 #else
174   return ::RemoveDirectory(strPath) ? true : false;
175 #endif
176 }
177
178 bool CHDDirectory::Exists(const char* strPath)
179 {
180   if (!strPath || !*strPath)
181     return false;
182   CStdString strReplaced=strPath;
183 #ifdef _WIN32
184   CStdStringW strWReplaced;
185   strReplaced.Replace("/","\\");
186   URIUtils::AddSlashAtEnd(strReplaced);
187   g_charsetConverter.utf8ToW(strReplaced, strWReplaced, false);
188   DWORD attributes = GetFileAttributesW(strWReplaced);
189 #else
190   DWORD attributes = GetFileAttributes(strReplaced.c_str());
191 #endif
192   if(attributes == INVALID_FILE_ATTRIBUTES)
193     return false;
194   if (FILE_ATTRIBUTE_DIRECTORY & attributes) return true;
195   return false;
196 }