blob: f6b94eb90a0b8164bd88689d84a17a4834040130 [file] [log] [blame]
Constantin Kaplinsky729598c2006-05-25 05:12:25 +00001/* Copyright (C) 2005 TightVNC Team. All Rights Reserved.
2 *
3 * Developed by Dennis Syrovatsky.
4 *
5 * This 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 of the License, or
8 * (at your option) any later version.
9 *
10 * This software 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 this software; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 * USA.
19 *
Peter Åstrand7877cd62009-02-25 16:15:48 +000020 *
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000021 *
22 */
23
24// -=- FolderManager.cxx
25
26#include <rfb_win32/FolderManager.h>
27
28using namespace rfb;
29using namespace rfb::win32;
30
31FolderManager::FolderManager()
32{
33
34}
35
36FolderManager::~FolderManager()
37{
38
39}
40
41bool
42FolderManager::createDir(char *pFullPath)
43{
44 if (CreateDirectory(pFullPath, NULL) == 0) return false;
45
46 return true;
47}
48
49bool
50FolderManager::renameIt(char *pPath, char *pOldName, char *pNewName)
51{
52 char fullOldName[FT_FILENAME_SIZE];
53 char fullNewName[FT_FILENAME_SIZE];
54
55 sprintf(fullOldName, "%s\\%s", pPath, pOldName);
56 sprintf(fullNewName, "%s\\%s", pPath, pNewName);
57
58 return renameIt(fullOldName, fullNewName);
59}
60
61bool
62FolderManager::renameIt(char *pOldName, char *pNewName)
63{
64 if (MoveFile(pOldName, pNewName)) return true;
65
66 return false;
67}
68
69bool
70FolderManager::deleteIt(char *pFullPath)
71{
72 FileInfo fileInfo;
73
74 FILEINFO FIStruct;
75 if (!getInfo(pFullPath, &FIStruct)) return false;
76
77 fileInfo.add(&FIStruct);
78
79 return deleteIt(&fileInfo);
80}
81
82bool
83FolderManager::deleteIt(char *pPrefix, FileInfo *pFI)
84{
85 char buf[FT_FILENAME_SIZE];
86 for (unsigned int i = 0; i < pFI->getNumEntries(); i++) {
87 sprintf(buf, "%s\\%s", pPrefix, pFI->getNameAt(i));
88 pFI->setNameAt(i,buf);
89 }
90 return deleteIt(pFI);
91}
92
93bool
94FolderManager::deleteIt(FileInfo *pFI)
95{
96 unsigned int num = pFI->getNumEntries();
97 unsigned int last = num - 1;
98
99 while (num > 0) {
100 if (pFI->getFlagsAt(last) & FT_ATTR_DIR) {
101 if (RemoveDirectory(pFI->getNameAt(last)) == 0) {
102 if (GetLastError() == ERROR_DIR_NOT_EMPTY) {
103 if (!getFolderInfoWithPrefix(pFI->getNameAt(last), pFI)) {
104 pFI->free();
105 return false;
106 }
107 }
108 } else {
109 pFI->deleteAt(last);
110 }
111 } else {
112 if (DeleteFile(pFI->getNameAt(last)) == 0) {
113 pFI->free();
114 return false;
115 } else {
116 pFI->deleteAt(last);
117 }
118 }
119 num = pFI->getNumEntries();
120 last = num - 1;
121 }
122
123 return true;
124}
125
126bool
127FolderManager::getFolderInfoWithPrefix(char *pPrefix, FileInfo *pFileInfo)
128{
129 char prefix[FT_FILENAME_SIZE];
130 strcpy(prefix, pPrefix);
131
132 FileInfo tmpFileInfo;
133 if (!getDirInfo(prefix, &tmpFileInfo, 0)) {
134 tmpFileInfo.free();
135 return false;
136 } else {
137 char buf[FT_FILENAME_SIZE];
138 for (unsigned int i = 0; i < tmpFileInfo.getNumEntries(); i++) {
139 sprintf(buf, "%s\\%s", prefix, tmpFileInfo.getNameAt(i));
140 pFileInfo->add(buf, tmpFileInfo.getSizeAt(i), tmpFileInfo.getDataAt(i), tmpFileInfo.getFlagsAt(i));
141 }
142 }
143 tmpFileInfo.free();
144 return true;
145}
146
147bool
148FolderManager::getDirInfo(char *pPath, FileInfo *pFileInfo, unsigned int dirOnly)
149{
150 if (strlen(pPath) == 0) return getDrivesInfo(pFileInfo);
151
152 char path[FT_FILENAME_SIZE];
153 sprintf(path, "%s\\*", pPath);
154
155 WIN32_FIND_DATA FindFileData;
156 SetErrorMode(SEM_FAILCRITICALERRORS);
157 HANDLE handle = FindFirstFile(path, &FindFileData);
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000158 SetErrorMode(0);
159
160 if (handle != INVALID_HANDLE_VALUE) {
161 do {
162 if (strcmp(FindFileData.cFileName, ".") != 0 &&
163 strcmp(FindFileData.cFileName, "..") != 0) {
164 unsigned int lastWriteTime = getTime70(FindFileData.ftLastWriteTime);
165 if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
166 pFileInfo->add(FindFileData.cFileName, 0, lastWriteTime, FT_ATTR_DIR);
167 } else {
168 if (!dirOnly)
169 pFileInfo->add(FindFileData.cFileName, FindFileData.nFileSizeLow, lastWriteTime, FT_ATTR_FILE);
170 }
171 }
172
173 } while (FindNextFile(handle, &FindFileData));
174 } else {
175 return false;
176 }
177 FindClose(handle);
178 return true;
179}
180
181bool
182FolderManager::getDrivesInfo(FileInfo *pFileInfo)
183{
184 TCHAR szDrivesList[256];
185 if (GetLogicalDriveStrings(255, szDrivesList) == 0)
186 return false;
187
188 int i = 0;
189 while (szDrivesList[i] != '\0') {
190 char *drive = strdup(&szDrivesList[i]);
191 char *backslash = strrchr(drive, '\\');
192 if (backslash != NULL)
193 *backslash = '\0';
194 pFileInfo->add(drive, 0, 0, FT_ATTR_DIR);
195 free(drive);
196 i += strcspn(&szDrivesList[i], "\0") + 1;
197 }
198 return true;
199}
200
201bool
202FolderManager::getInfo(char *pFullPath, FILEINFO *pFIStruct)
203{
204 WIN32_FIND_DATA FindFileData;
205 SetErrorMode(SEM_FAILCRITICALERRORS);
206 HANDLE hFile = FindFirstFile(pFullPath, &FindFileData);
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000207 SetErrorMode(0);
208 if (hFile != INVALID_HANDLE_VALUE) {
209 FindClose(hFile);
210 strcpy(pFIStruct->name, pFullPath);
211 pFIStruct->info.data = getTime70(FindFileData.ftLastWriteTime);
212 if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
213 pFIStruct->info.size = 0;
214 pFIStruct->info.flags = FT_ATTR_DIR;
215 return true;
216 } else {
217 pFIStruct->info.size = FindFileData.nFileSizeLow;
218 pFIStruct->info.flags = FT_ATTR_FILE;
219 return true;
220 }
221 }
222 return false;
223}
224
225unsigned int
226FolderManager::getTime70(FILETIME ftime)
227{
228 LARGE_INTEGER uli;
229 uli.LowPart = ftime.dwLowDateTime;
230 uli.HighPart = ftime.dwHighDateTime;
Peter Åstrand06eee262008-12-09 12:46:47 +0000231 uli.QuadPart = (uli.QuadPart - 116444736000000000LL) / 10000000;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000232 return uli.LowPart;
233}
234
235void
236FolderManager::getFiletime(unsigned int time70, FILETIME *pftime)
237{
Peter Åstrand06eee262008-12-09 12:46:47 +0000238 LONGLONG ll = Int32x32To64(time70, 10000000) + 116444736000000000LL;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000239 pftime->dwLowDateTime = (DWORD) ll;
240 pftime->dwHighDateTime = (DWORD) (ll >> 32);
241}
242
243bool
244FolderManager::getDirSize(char *pFullPath, DWORD64 *dirSize)
245{
246 char fullPath[FT_FILENAME_SIZE];
247 FileInfo fi;
248 fi.add(pFullPath, 0, 0, FT_ATTR_DIR);
249 DWORD64 dirFileSize64 = 0;
250 do {
251 sprintf(fullPath, "%s\\*", fi.getNameAt(0));
252 WIN32_FIND_DATA FindFileData;
253 SetErrorMode(SEM_FAILCRITICALERRORS);
254 HANDLE hFile = FindFirstFile(fullPath, &FindFileData);
255 SetErrorMode(0);
256
257 if (hFile != INVALID_HANDLE_VALUE) {
258 do {
259 if (strcmp(FindFileData.cFileName, ".") != 0 &&
260 strcmp(FindFileData.cFileName, "..") != 0) {
261 char buff[MAX_PATH];
262 if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
263 sprintf(buff, "%s\\%s", fi.getNameAt(0), FindFileData.cFileName);
264 fi.add(buff, 0, 0, FT_ATTR_DIR);
265 } else {
266 dirFileSize64 += FindFileData.nFileSizeLow;
267 }
268 }
269 } while (FindNextFile(hFile, &FindFileData));
270 FindClose(hFile);
271 }
272 fi.deleteAt(0);
273 } while (fi.getNumEntries() > 0);
274
275 *dirSize = dirFileSize64;
276 return true;
Peter Åstrand06eee262008-12-09 12:46:47 +0000277}