blob: 3ab49a1cce071685aaf90053e85071dc84333ba8 [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 *
20 * TightVNC distribution homepage on the Web: http://www.tightvnc.com/
21 *
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);
158 DWORD lastError = GetLastError();
159 SetErrorMode(0);
160
161 if (handle != INVALID_HANDLE_VALUE) {
162 do {
163 if (strcmp(FindFileData.cFileName, ".") != 0 &&
164 strcmp(FindFileData.cFileName, "..") != 0) {
165 unsigned int lastWriteTime = getTime70(FindFileData.ftLastWriteTime);
166 if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
167 pFileInfo->add(FindFileData.cFileName, 0, lastWriteTime, FT_ATTR_DIR);
168 } else {
169 if (!dirOnly)
170 pFileInfo->add(FindFileData.cFileName, FindFileData.nFileSizeLow, lastWriteTime, FT_ATTR_FILE);
171 }
172 }
173
174 } while (FindNextFile(handle, &FindFileData));
175 } else {
176 return false;
177 }
178 FindClose(handle);
179 return true;
180}
181
182bool
183FolderManager::getDrivesInfo(FileInfo *pFileInfo)
184{
185 TCHAR szDrivesList[256];
186 if (GetLogicalDriveStrings(255, szDrivesList) == 0)
187 return false;
188
189 int i = 0;
190 while (szDrivesList[i] != '\0') {
191 char *drive = strdup(&szDrivesList[i]);
192 char *backslash = strrchr(drive, '\\');
193 if (backslash != NULL)
194 *backslash = '\0';
195 pFileInfo->add(drive, 0, 0, FT_ATTR_DIR);
196 free(drive);
197 i += strcspn(&szDrivesList[i], "\0") + 1;
198 }
199 return true;
200}
201
202bool
203FolderManager::getInfo(char *pFullPath, FILEINFO *pFIStruct)
204{
205 WIN32_FIND_DATA FindFileData;
206 SetErrorMode(SEM_FAILCRITICALERRORS);
207 HANDLE hFile = FindFirstFile(pFullPath, &FindFileData);
208 DWORD lastError = GetLastError();
209 SetErrorMode(0);
210 if (hFile != INVALID_HANDLE_VALUE) {
211 FindClose(hFile);
212 strcpy(pFIStruct->name, pFullPath);
213 pFIStruct->info.data = getTime70(FindFileData.ftLastWriteTime);
214 if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
215 pFIStruct->info.size = 0;
216 pFIStruct->info.flags = FT_ATTR_DIR;
217 return true;
218 } else {
219 pFIStruct->info.size = FindFileData.nFileSizeLow;
220 pFIStruct->info.flags = FT_ATTR_FILE;
221 return true;
222 }
223 }
224 return false;
225}
226
227unsigned int
228FolderManager::getTime70(FILETIME ftime)
229{
230 LARGE_INTEGER uli;
231 uli.LowPart = ftime.dwLowDateTime;
232 uli.HighPart = ftime.dwHighDateTime;
Peter Åstrand06eee262008-12-09 12:46:47 +0000233 uli.QuadPart = (uli.QuadPart - 116444736000000000LL) / 10000000;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000234 return uli.LowPart;
235}
236
237void
238FolderManager::getFiletime(unsigned int time70, FILETIME *pftime)
239{
Peter Åstrand06eee262008-12-09 12:46:47 +0000240 LONGLONG ll = Int32x32To64(time70, 10000000) + 116444736000000000LL;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000241 pftime->dwLowDateTime = (DWORD) ll;
242 pftime->dwHighDateTime = (DWORD) (ll >> 32);
243}
244
245bool
246FolderManager::getDirSize(char *pFullPath, DWORD64 *dirSize)
247{
248 char fullPath[FT_FILENAME_SIZE];
249 FileInfo fi;
250 fi.add(pFullPath, 0, 0, FT_ATTR_DIR);
251 DWORD64 dirFileSize64 = 0;
252 do {
253 sprintf(fullPath, "%s\\*", fi.getNameAt(0));
254 WIN32_FIND_DATA FindFileData;
255 SetErrorMode(SEM_FAILCRITICALERRORS);
256 HANDLE hFile = FindFirstFile(fullPath, &FindFileData);
257 SetErrorMode(0);
258
259 if (hFile != INVALID_HANDLE_VALUE) {
260 do {
261 if (strcmp(FindFileData.cFileName, ".") != 0 &&
262 strcmp(FindFileData.cFileName, "..") != 0) {
263 char buff[MAX_PATH];
264 if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
265 sprintf(buff, "%s\\%s", fi.getNameAt(0), FindFileData.cFileName);
266 fi.add(buff, 0, 0, FT_ATTR_DIR);
267 } else {
268 dirFileSize64 += FindFileData.nFileSizeLow;
269 }
270 }
271 } while (FindNextFile(hFile, &FindFileData));
272 FindClose(hFile);
273 }
274 fi.deleteAt(0);
275 } while (fi.getNumEntries() > 0);
276
277 *dirSize = dirFileSize64;
278 return true;
Peter Åstrand06eee262008-12-09 12:46:47 +0000279}