blob: 06daf311eeb085583ac0593dcc6f3d65ea98bb58 [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
47bool
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +000048FolderManager::renameIt(char *pOldName, char *pNewName)
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000049{
Dennis Syrovatsky514c3072005-10-19 07:34:40 +000050 if (MoveFile(pOldName, pNewName)) return true;
51
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000052 return false;
53}
54
55bool
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +000056FolderManager::deleteIt(char *pFullPath)
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +000057{
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000058 FileInfo fileInfo;
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +000059
60 FILEINFO FIStruct;
61 if (!getInfo(pFullPath, &FIStruct)) return false;
62
63 fileInfo.add(&FIStruct);
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000064
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000065 return deleteIt(&fileInfo);
66}
67
68bool
69FolderManager::deleteIt(char *pPrefix, FileInfo *pFI)
70{
71 char buf[FT_FILENAME_SIZE];
72 for (unsigned int i = 0; i < pFI->getNumEntries(); i++) {
73 sprintf(buf, "%s\\%s", pPrefix, pFI->getNameAt(i));
74 pFI->setNameAt(i,buf);
75 }
76 return deleteIt(pFI);
77}
78
79bool
80FolderManager::deleteIt(FileInfo *pFI)
81{
82 unsigned int num = pFI->getNumEntries();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000083 unsigned int last = num - 1;
84
85 while (num > 0) {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000086 if (pFI->getFlagsAt(last) & FT_ATTR_DIR) {
87 if (RemoveDirectory(pFI->getNameAt(last)) == 0) {
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000088 if (GetLastError() == ERROR_DIR_NOT_EMPTY) {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000089 if (!getFolderInfoWithPrefix(pFI->getNameAt(last), pFI)) {
90 pFI->free();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000091 return false;
92 }
93 }
94 } else {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000095 pFI->deleteAt(last);
Dennis Syrovatsky880318b2005-10-19 10:05:51 +000096 }
97 } else {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000098 if (DeleteFile(pFI->getNameAt(last)) == 0) {
99 pFI->free();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000100 return false;
101 } else {
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000102 pFI->deleteAt(last);
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000103 }
104 }
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000105 num = pFI->getNumEntries();
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000106 last = num - 1;
107 }
108
109 return true;
110}
111
112bool
113FolderManager::getFolderInfoWithPrefix(char *pPrefix, FileInfo *pFileInfo)
114{
115 char prefix[FT_FILENAME_SIZE];
116 strcpy(prefix, pPrefix);
117
118 FileInfo tmpFileInfo;
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000119 if (!getDirInfo(prefix, &tmpFileInfo, 0)) {
Dennis Syrovatsky880318b2005-10-19 10:05:51 +0000120 tmpFileInfo.free();
121 return false;
122 } else {
123 char buf[FT_FILENAME_SIZE];
124 for (unsigned int i = 0; i < tmpFileInfo.getNumEntries(); i++) {
125 sprintf(buf, "%s\\%s", prefix, tmpFileInfo.getNameAt(i));
126 pFileInfo->add(buf, tmpFileInfo.getSizeAt(i), tmpFileInfo.getDataAt(i), tmpFileInfo.getFlagsAt(i));
127 }
128 }
129 tmpFileInfo.free();
130 return true;
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +0000131}
132
133bool
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000134FolderManager::getDirInfo(char *pPath, FileInfo *pFileInfo, unsigned int dirOnly)
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +0000135{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000136 if (strlen(pPath) == 0) return getDrivesInfo(pFileInfo);
137
138 char path[FT_FILENAME_SIZE];
139 sprintf(path, "%s\\*", pPath);
140
141 WIN32_FIND_DATA FindFileData;
142 SetErrorMode(SEM_FAILCRITICALERRORS);
143 HANDLE handle = FindFirstFile(path, &FindFileData);
144 DWORD lastError = GetLastError();
145 SetErrorMode(0);
146
147 if (handle != INVALID_HANDLE_VALUE) {
148 do {
149 if (strcmp(FindFileData.cFileName, ".") != 0 &&
150 strcmp(FindFileData.cFileName, "..") != 0) {
151 unsigned int lastWriteTime = getTime70(FindFileData.ftLastWriteTime);
152 if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
153 pFileInfo->add(FindFileData.cFileName, 0, lastWriteTime, FT_ATTR_DIR);
154 } else {
155 if (!dirOnly)
156 pFileInfo->add(FindFileData.cFileName, FindFileData.nFileSizeLow, lastWriteTime, FT_ATTR_FILE);
157 }
158 }
159
160 } while (FindNextFile(handle, &FindFileData));
161 } else {
162 return false;
163 }
164 FindClose(handle);
165 return true;
Dennis Syrovatsky84ea20f2005-10-19 07:46:31 +0000166}
167
168bool
169FolderManager::getDrivesInfo(FileInfo *pFileInfo)
170{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000171 TCHAR szDrivesList[256];
172 if (GetLogicalDriveStrings(255, szDrivesList) == 0)
173 return false;
174
175 int i = 0;
176 while (szDrivesList[i] != '\0') {
177 char *drive = strdup(&szDrivesList[i]);
178 char *backslash = strrchr(drive, '\\');
179 if (backslash != NULL)
180 *backslash = '\0';
181 pFileInfo->add(drive, 0, 0, FT_ATTR_DIR);
182 free(drive);
183 i += strcspn(&szDrivesList[i], "\0") + 1;
184 }
185 return true;
Dennis Syrovatsky110e7ee2005-10-19 07:01:41 +0000186}
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000187
188bool
189FolderManager::getInfo(char *pFullPath, FILEINFO *pFIStruct)
190{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000191 WIN32_FIND_DATA FindFileData;
192 SetErrorMode(SEM_FAILCRITICALERRORS);
193 HANDLE hFile = FindFirstFile(pFullPath, &FindFileData);
194 DWORD lastError = GetLastError();
195 SetErrorMode(0);
196 if (hFile != INVALID_HANDLE_VALUE) {
197 FindClose(hFile);
Dennis Syrovatsky922ee6a2005-12-05 10:55:51 +0000198 strcpy(pFIStruct->name, pFullPath);
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000199 pFIStruct->info.data = getTime70(FindFileData.ftLastWriteTime);
200 if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
201 pFIStruct->info.size = 0;
202 pFIStruct->info.flags = FT_ATTR_DIR;
203 return true;
204 } else {
205 pFIStruct->info.size = FindFileData.nFileSizeLow;
206 pFIStruct->info.flags = FT_ATTR_FILE;
207 return true;
208 }
209 }
210 return false;
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000211}
212
213unsigned int
214FolderManager::getTime70(FILETIME ftime)
215{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000216 LARGE_INTEGER uli;
217 uli.LowPart = ftime.dwLowDateTime;
218 uli.HighPart = ftime.dwHighDateTime;
219 uli.QuadPart = (uli.QuadPart - 116444736000000000) / 10000000;
220 return uli.LowPart;
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000221}
222
223void
224FolderManager::getFiletime(unsigned int time70, FILETIME *pftime)
225{
Dennis Syrovatskyf3c57662005-11-02 03:53:04 +0000226 LONGLONG ll = Int32x32To64(time70, 10000000) + 116444736000000000;
227 pftime->dwLowDateTime = (DWORD) ll;
228 pftime->dwHighDateTime = (DWORD) (ll >> 32);
Dennis Syrovatsky05c448f2005-10-26 01:10:22 +0000229}
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000230
231bool
232FolderManager::getDirSize(char *pFullPath, DWORD64 *dirSize)
233{
234 char fullPath[FT_FILENAME_SIZE];
235 FileInfo fi;
236 fi.add(pFullPath, 0, 0, FT_ATTR_DIR);
237 DWORD64 dirFileSize64 = 0;
238 do {
239 sprintf(fullPath, "%s\\*", fi.getNameAt(0));
240 WIN32_FIND_DATA FindFileData;
241 SetErrorMode(SEM_FAILCRITICALERRORS);
242 HANDLE hFile = FindFirstFile(fullPath, &FindFileData);
243 SetErrorMode(0);
244
245 if (hFile != INVALID_HANDLE_VALUE) {
246 do {
247 if (strcmp(FindFileData.cFileName, ".") != 0 &&
248 strcmp(FindFileData.cFileName, "..") != 0) {
249 char buff[MAX_PATH];
250 if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
251 sprintf(buff, "%s\\%s", fi.getNameAt(0), FindFileData.cFileName);
252 fi.add(buff, 0, 0, FT_ATTR_DIR);
253 } else {
254 dirFileSize64 += FindFileData.nFileSizeLow;
255 }
256 }
257 } while (FindNextFile(hFile, &FindFileData));
258 FindClose(hFile);
259 }
260 fi.deleteAt(0);
261 } while (fi.getNumEntries() > 0);
262
263 *dirSize = dirFileSize64;
264 return true;
265}