blob: 349e0f75c93e5b35850555623209d49bbcb847d1 [file] [log] [blame]
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +00001/* Copyright (C) 2005 TightVNC Team. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 *
18 * TightVNC distribution homepage on the Web: http://www.tightvnc.com/
19 *
20 */
21
22// -=- FolderManager.cxx
23
24#include <rfb_win32/FolderManager.h>
25
26using namespace rfb;
27using namespace rfb::win32;
28
29FolderManager::FolderManager()
30{
31
32}
33
34FolderManager::~FolderManager()
35{
36
37}
38
39bool
40FolderManager::createDir(char *pFullPath)
41{
Dennis Syrovatsky514c3072005-10-19 07:34:40 +000042 if (CreateDirectory(pFullPath, NULL) == 0) return false;
43
44 return true;
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000045}
46
Dennis Syrovatsky95509432005-12-14 16:42:33 +000047bool
48FolderManager::renameIt(char *pPath, char *pOldName, char *pNewName)
49{
50 char fullOldName[FT_FILENAME_SIZE];
51 char fullNewName[FT_FILENAME_SIZE];
52
53 sprintf(fullOldName, "%s\\%s", pPath, pOldName);
54 sprintf(fullNewName, "%s\\%s", pPath, pNewName);
55
56 return renameIt(fullOldName, fullNewName);
57}
58
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000059bool
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +000060FolderManager::renameIt(char *pOldName, char *pNewName)
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000061{
Dennis Syrovatsky514c3072005-10-19 07:34:40 +000062 if (MoveFile(pOldName, pNewName)) return true;
63
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000064 return false;
65}
66
67bool
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +000068FolderManager::deleteIt(char *pFullPath)
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000069{
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000070 FileInfo fileInfo;
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +000071
72 FILEINFO FIStruct;
73 if (!getInfo(pFullPath, &FIStruct)) return false;
74
75 fileInfo.add(&FIStruct);
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000076
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000077 return deleteIt(&fileInfo);
78}
79
80bool
81FolderManager::deleteIt(char *pPrefix, FileInfo *pFI)
82{
83 char buf[FT_FILENAME_SIZE];
84 for (unsigned int i = 0; i < pFI->getNumEntries(); i++) {
85 sprintf(buf, "%s\\%s", pPrefix, pFI->getNameAt(i));
86 pFI->setNameAt(i,buf);
87 }
88 return deleteIt(pFI);
89}
90
91bool
92FolderManager::deleteIt(FileInfo *pFI)
93{
94 unsigned int num = pFI->getNumEntries();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000095 unsigned int last = num - 1;
96
97 while (num > 0) {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000098 if (pFI->getFlagsAt(last) & FT_ATTR_DIR) {
99 if (RemoveDirectory(pFI->getNameAt(last)) == 0) {
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000100 if (GetLastError() == ERROR_DIR_NOT_EMPTY) {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000101 if (!getFolderInfoWithPrefix(pFI->getNameAt(last), pFI)) {
102 pFI->free();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000103 return false;
104 }
105 }
106 } else {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000107 pFI->deleteAt(last);
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000108 }
109 } else {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000110 if (DeleteFile(pFI->getNameAt(last)) == 0) {
111 pFI->free();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000112 return false;
113 } else {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000114 pFI->deleteAt(last);
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000115 }
116 }
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000117 num = pFI->getNumEntries();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000118 last = num - 1;
119 }
120
121 return true;
122}
123
124bool
125FolderManager::getFolderInfoWithPrefix(char *pPrefix, FileInfo *pFileInfo)
126{
127 char prefix[FT_FILENAME_SIZE];
128 strcpy(prefix, pPrefix);
129
130 FileInfo tmpFileInfo;
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000131 if (!getDirInfo(prefix, &tmpFileInfo, 0)) {
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000132 tmpFileInfo.free();
133 return false;
134 } else {
135 char buf[FT_FILENAME_SIZE];
136 for (unsigned int i = 0; i < tmpFileInfo.getNumEntries(); i++) {
137 sprintf(buf, "%s\\%s", prefix, tmpFileInfo.getNameAt(i));
138 pFileInfo->add(buf, tmpFileInfo.getSizeAt(i), tmpFileInfo.getDataAt(i), tmpFileInfo.getFlagsAt(i));
139 }
140 }
141 tmpFileInfo.free();
142 return true;
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +0000143}
144
145bool
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000146FolderManager::getDirInfo(char *pPath, FileInfo *pFileInfo, unsigned int dirOnly)
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +0000147{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000148 if (strlen(pPath) == 0) return getDrivesInfo(pFileInfo);
149
150 char path[FT_FILENAME_SIZE];
151 sprintf(path, "%s\\*", pPath);
152
153 WIN32_FIND_DATA FindFileData;
154 SetErrorMode(SEM_FAILCRITICALERRORS);
155 HANDLE handle = FindFirstFile(path, &FindFileData);
156 DWORD lastError = GetLastError();
157 SetErrorMode(0);
158
159 if (handle != INVALID_HANDLE_VALUE) {
160 do {
161 if (strcmp(FindFileData.cFileName, ".") != 0 &&
162 strcmp(FindFileData.cFileName, "..") != 0) {
163 unsigned int lastWriteTime = getTime70(FindFileData.ftLastWriteTime);
164 if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
165 pFileInfo->add(FindFileData.cFileName, 0, lastWriteTime, FT_ATTR_DIR);
166 } else {
167 if (!dirOnly)
168 pFileInfo->add(FindFileData.cFileName, FindFileData.nFileSizeLow, lastWriteTime, FT_ATTR_FILE);
169 }
170 }
171
172 } while (FindNextFile(handle, &FindFileData));
173 } else {
174 return false;
175 }
176 FindClose(handle);
177 return true;
Dennis Syrovatsky84ea20f2005-10-19 07:46:31 +0000178}
179
180bool
181FolderManager::getDrivesInfo(FileInfo *pFileInfo)
182{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000183 TCHAR szDrivesList[256];
184 if (GetLogicalDriveStrings(255, szDrivesList) == 0)
185 return false;
186
187 int i = 0;
188 while (szDrivesList[i] != '\0') {
189 char *drive = strdup(&szDrivesList[i]);
190 char *backslash = strrchr(drive, '\\');
191 if (backslash != NULL)
192 *backslash = '\0';
193 pFileInfo->add(drive, 0, 0, FT_ATTR_DIR);
194 free(drive);
195 i += strcspn(&szDrivesList[i], "\0") + 1;
196 }
197 return true;
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +0000198}
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000199
200bool
201FolderManager::getInfo(char *pFullPath, FILEINFO *pFIStruct)
202{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000203 WIN32_FIND_DATA FindFileData;
204 SetErrorMode(SEM_FAILCRITICALERRORS);
205 HANDLE hFile = FindFirstFile(pFullPath, &FindFileData);
206 DWORD lastError = GetLastError();
207 SetErrorMode(0);
208 if (hFile != INVALID_HANDLE_VALUE) {
209 FindClose(hFile);
Dennis Syrovatsky922ee6a2005-12-05 10:55:51 +0000210 strcpy(pFIStruct->name, pFullPath);
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000211 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;
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000223}
224
225unsigned int
226FolderManager::getTime70(FILETIME ftime)
227{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000228 LARGE_INTEGER uli;
229 uli.LowPart = ftime.dwLowDateTime;
230 uli.HighPart = ftime.dwHighDateTime;
231 uli.QuadPart = (uli.QuadPart - 116444736000000000) / 10000000;
232 return uli.LowPart;
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000233}
234
235void
236FolderManager::getFiletime(unsigned int time70, FILETIME *pftime)
237{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000238 LONGLONG ll = Int32x32To64(time70, 10000000) + 116444736000000000;
239 pftime->dwLowDateTime = (DWORD) ll;
240 pftime->dwHighDateTime = (DWORD) (ll >> 32);
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000241}
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000242
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;
277}