blob: a9c4738f126fbb3720549a18d7cc0def9259bea7 [file] [log] [blame]
Dennis Syrovatsky139d7832005-11-02 05:36:05 +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// -=- FileTransfer.cxx
23
24#include <vncviewer/FileTransfer.h>
25
26using namespace rfb;
27using namespace rfb::win32;
28
29FileTransfer::FileTransfer()
30{
Dennis Syrovatsky4ab41852005-11-07 09:52:36 +000031 m_bFTDlgShown = false;
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000032 m_bInitialized = false;
33
Dennis Syrovatsky4ab41852005-11-07 09:52:36 +000034 m_pFTDialog = new FTDialog(GetModuleHandle(0), this);
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000035
36 m_pReader = NULL;
37 m_pWriter = NULL;
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +000038
39 m_dw64SizeSending = 0;
40 m_dirSizeRqstNum = 0;
Dennis Syrovatsky139d7832005-11-02 05:36:05 +000041}
42
43FileTransfer::~FileTransfer()
44{
Dennis Syrovatsky4ab41852005-11-07 09:52:36 +000045 if (m_pFTDialog != NULL) {
46 delete m_pFTDialog;
47 m_pFTDialog = NULL;
48 }
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000049
50 freeQueues();
Dennis Syrovatsky4ab41852005-11-07 09:52:36 +000051}
Dennis Syrovatsky139d7832005-11-02 05:36:05 +000052
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000053bool
54FileTransfer::initialize(rdr::InStream *pIS, rdr::OutStream *pOS)
55{
56 if (m_bInitialized) return false;
57
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000058 m_pReader = new FTMsgReader(pIS);
59 m_pWriter = new FTMsgWriter(pOS);
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000060
Dennis Syrovatsky29440e82005-12-05 09:31:28 +000061 freeQueues();
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +000062
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000063 m_bInitialized = true;
64 return true;
65}
66
67bool
Dennis Syrovatsky4905c8f2005-11-21 15:52:46 +000068FileTransfer::show(HWND hwndParent)
Dennis Syrovatsky4ab41852005-11-07 09:52:36 +000069{
Dennis Syrovatskyda17d212005-11-09 05:58:30 +000070 if (!m_bInitialized) return false;
71
Dennis Syrovatsky4905c8f2005-11-21 15:52:46 +000072 m_bFTDlgShown = m_pFTDialog->createFTDialog(hwndParent);
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +000073
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000074 return m_bFTDlgShown;
Dennis Syrovatsky139d7832005-11-02 05:36:05 +000075}
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000076
77bool
78FileTransfer::processFTMsg(int type)
79{
Dennis Syrovatsky514555b2005-11-21 14:40:56 +000080 if (!m_bInitialized) return false;
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000081
82 switch (type)
83 {
84 case msgTypeFileListData:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000085 return procFileListDataMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000086 case msgTypeFileDownloadData:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000087 return procFileDownloadDataMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000088 case msgTypeFileUploadCancel:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000089 return procFileUploadCancelMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000090 case msgTypeFileDownloadFailed:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000091 return procFileDownloadFailedMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000092 case msgTypeFileDirSizeData:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000093 return procFileDirSizeDataMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000094 case msgTypeFileLastRequestFailed:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000095 return procFileLastRqstFailedMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000096 default:
97 return false;
98 }
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000099}
Dennis Syrovatsky63943a32005-11-10 06:24:56 +0000100
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +0000101bool
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000102FileTransfer::isTransferEnable()
103{
104 if (m_TransferQueue.getNumEntries() > 0) return true; else return false;
105}
106
107void
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000108FileTransfer::addDeleteQueue(char *pPathPrefix, FileInfo *pFI, unsigned int flags)
109{
110 m_DeleteQueue.add(pPathPrefix, "", pFI, flags);
111
112 checkDeleteQueue();
113}
114
115void
116FileTransfer::checkDeleteQueue()
117{
118
119}
120
121void
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000122FileTransfer::addTransferQueue(char *pLocalPath, char *pRemotePath,
123 FileInfo *pFI, unsigned int flags)
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000124{
125 if ((m_bFTDlgShown) && (!isTransferEnable())) m_pFTDialog->setStatusText("Starting Copy Operation");
126
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000127 m_TransferQueue.add(pLocalPath, pRemotePath, pFI, (flags | FT_ATTR_RESIZE_NEEDED));
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000128
129 checkTransferQueue();
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000130}
131
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000132bool
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000133FileTransfer::resizeSending()
134{
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000135 for (unsigned int i = 0; i < m_TransferQueue.getNumEntries(); i++) {
136 unsigned int flags = m_TransferQueue.getFlagsAt(i);
137 if (flags & FT_ATTR_RESIZE_NEEDED) {
138 if (flags & FT_ATTR_FILE) {
139 m_dw64SizeSending += m_TransferQueue.getSizeAt(i);
140 m_TransferQueue.clearFlagAt(i, FT_ATTR_RESIZE_NEEDED);
141 } else {
142 if (flags & FT_ATTR_DIR) {
143 if (flags & FT_ATTR_COPY_DOWNLOAD) {
144 char *pPath = m_TransferQueue.getFullRemPathAt(i);
145 m_dirSizeRqstNum = i;
146 m_pWriter->writeFileDirSizeRqst(strlen(pPath), pPath);
147 return false;
148 } else {
149 if (flags & FT_ATTR_COPY_UPLOAD) {
150 FolderManager fm;
151 DWORD64 dw64Size;
152 fm.getDirSize(m_TransferQueue.getFullLocPathAt(i), &dw64Size);
153 m_dw64SizeSending += dw64Size;
154 m_TransferQueue.clearFlagAt(i, FT_ATTR_RESIZE_NEEDED);
155 }
156 } // if (flags & FT_ATTR_COPY_DOWNLOAD)
157 } // if (flags & FT_ATTR_FOLDER)
158 } // if (flags & FT_ATTR_FILE)
159 } // if (flags & FT_ATTR_NEEDED_RESIZE)
160 } // for (unsigned int i = 0; i < m_TransferQueue.getNumEntries(); i++)
161 return true;
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000162}
163
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000164void
165FileTransfer::checkTransferQueue()
166{
167 if (!isTransferEnable()) {
168 if (m_bFTDlgShown) {
169 m_pFTDialog->setStatusText("File Transfer Operation Completed Successfully");
170 PostMessage(m_pFTDialog->getWndHandle(), WM_COMMAND, MAKEWPARAM(IDC_FTLOCALRELOAD, 0), 0);
171 PostMessage(m_pFTDialog->getWndHandle(), WM_COMMAND, MAKEWPARAM(IDC_FTREMOTERELOAD, 0), 0);
172 return;
173 }
174 } else {
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000175 if (!resizeSending()) return;
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000176
177 unsigned int flag0 = m_TransferQueue.getFlagsAt(0);
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000178
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000179 if (flag0 & FT_ATTR_COPY_UPLOAD) {
180 if (flag0 & FT_ATTR_FILE) {
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000181 uploadFile();
182 return;
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000183 }
184 if (flag0 & FT_ATTR_DIR) {
185 char *pFullPath = m_TransferQueue.getFullRemPathAt(0);
186 if (m_bFTDlgShown) m_pFTDialog->setStatusText("Creating Remote Folder. %s", pFullPath);
187 m_pWriter->writeFileCreateDirRqst(strlen(pFullPath), pFullPath);
188
189 char *pPath = m_TransferQueue.getRemPathAt(0);
190 m_TransferQueue.setFlagsAt(0, (flag0 | FT_ATTR_FLR_UPLOAD_CHECK));
191 m_queueFileListRqst.add(pPath, 0, 0, FT_FLR_DEST_UPLOAD);
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000192 m_pWriter->writeFileListRqst(strlen(pPath), pPath, false);
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000193 return;
194 }
195 } else {
196 if (flag0 & FT_ATTR_COPY_DOWNLOAD) {
197 if (flag0 & FT_ATTR_FILE) {
198 }
199 if (flag0 & FT_ATTR_DIR) {
200 }
201 }
202 }
203 if (m_bFTDlgShown) m_pFTDialog->setStatusText("File Transfer Operation Failed. Unknown data in the transfer queue");
204
205 } // if (!isTransferEnable())
206}
207
208bool
209FileTransfer::uploadFile()
210{
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000211 if (m_TransferQueue.getFlagsAt(0) & FT_ATTR_FILE) {
212 if (m_fileReader.create(m_TransferQueue.getFullLocPathAt(0))) {
213 m_pWriter->writeFileUploadRqst(strlen(m_TransferQueue.getFullRemPathAt(0)),
214 m_TransferQueue.getFullRemPathAt(0), 0);
215 uploadFilePortion();
216 }
217 }
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000218 return false;
219}
220
221bool
222FileTransfer::downloadFile()
223{
224 return false;
225}
226
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000227void
228FileTransfer::uploadFilePortion()
229{
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000230 if (m_fileReader.isCreated()) {
231 char buf[FT_MAX_SENDING_SIZE];
232 unsigned int bytesRead = 0;
233 if (m_fileReader.read((void *)buf, FT_MAX_SENDING_SIZE, &bytesRead)) {
234 if (bytesRead == 0) {
235 m_pWriter->writeFileUploadData(m_TransferQueue.getDataAt(0));
236 m_fileReader.close();
237 m_TransferQueue.deleteAt(0);
238 m_pFTDialog->postCheckTransferQueueMsg();
239 } else {
240 m_pWriter->writeFileUploadData(bytesRead, (char *)buf);
241 m_pFTDialog->postUploadFilePortionMsg();
242 }
243 } else {
244 m_fileReader.close();
245 m_TransferQueue.deleteAt(0);
246 m_pFTDialog->postCheckTransferQueueMsg();
247 }
248 }
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000249}
250
251void
252FileTransfer::downloadFilePortion()
253{
254
255}
256
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000257bool
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +0000258FileTransfer::procFileListDataMsg()
259{
Dennis Syrovatsky8b194ee2005-11-10 08:56:34 +0000260 FileInfo fileInfo;
261 int res = m_pReader->readFileListData(&fileInfo);
262
263 bool bResult;
264 switch (m_queueFileListRqst.getFlagsAt(0))
265 {
266 case FT_FLR_DEST_MAIN:
267 if (!m_bFTDlgShown) break;
268
269 if (res < 0) {
270 m_pFTDialog->reqFolderUnavailable();
271 bResult = true;
272 } else {
273 bResult = procFLRMain(&fileInfo);
274 }
275 break;
276 case FT_FLR_DEST_BROWSE:
277 bResult = procFLRBrowse(&fileInfo);
278 break;
279 case FT_FLR_DEST_UPLOAD:
280 bResult = procFLRUpload(&fileInfo);
281 break;
282 case FT_FLR_DEST_DOWNLOAD:
283 bResult = procFLRDownload(&fileInfo);
284 break;
285 case FT_FLR_DEST_DELETE:
286 bResult = procFLRDelete(&fileInfo);
287 break;
288 case FT_FLR_DEST_RENAME:
289 bResult = procFLRRename(&fileInfo);
290 break;
291 }
292 m_queueFileListRqst.deleteAt(0);
293 return bResult;
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +0000294}
295
296bool
297FileTransfer::procFileDownloadDataMsg()
298{
299 return false;
300}
301
302bool
303FileTransfer::procFileUploadCancelMsg()
304{
305 return false;
306}
307
308bool
309FileTransfer::procFileDownloadFailedMsg()
310{
311 return false;
312}
313
314bool
315FileTransfer::procFileDirSizeDataMsg()
316{
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000317 DWORD64 dw64DirSize = 0;
318 m_pReader->readFileDirSizeData(&dw64DirSize);
319 m_TransferQueue.clearFlagAt(m_dirSizeRqstNum, FT_ATTR_RESIZE_NEEDED);
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000320 checkTransferQueue();
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000321 return true;
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +0000322}
323
324bool
325FileTransfer::procFileLastRqstFailedMsg()
326{
327 return false;
328}
Dennis Syrovatsky8b194ee2005-11-10 08:56:34 +0000329
330bool
331FileTransfer::procFLRMain(FileInfo *pFI)
332{
333 if (m_bFTDlgShown) m_pFTDialog->addRemoteLVItems(pFI);
334 return true;
335}
336
337bool
338FileTransfer::procFLRBrowse(FileInfo *pFI)
339{
340 return false;
341}
342
343bool
344FileTransfer::procFLRUpload(FileInfo *pFI)
345{
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000346 unsigned int flags = m_TransferQueue.getFlagsAt(0);
347 if (flags & FT_ATTR_FLR_UPLOAD_CHECK) {
348 int num = isExistName(pFI, m_TransferQueue.getRemNameAt(0));
349 if (num >= 0) {
350 if ((m_bFTDlgShown) && (strcmp(m_TransferQueue.getRemPathAt(0), m_pFTDialog->getRemotePath()) == 0)) {
351 m_pFTDialog->addRemoteLVItems(pFI);
352 }
353 } else {
354 if (flags & FT_ATTR_DIR) {
355 m_TransferQueue.deleteAt(0);
356 if (m_bFTDlgShown) m_pFTDialog->setStatusText("Create Remote Folder Failed.");
357 }
358 }
359 }
360 FolderManager fm;
361 FileInfo fi;
362 flags = m_TransferQueue.getFlagsAt(0);
363 if (flags & FT_ATTR_FILE) {
364 uploadFile();
365 return true;
366 } else {
367 if (fm.getDirInfo(m_TransferQueue.getFullLocPathAt(0), &fi, 0)) {
368 m_TransferQueue.add(m_TransferQueue.getFullLocPathAt(0),
369 m_TransferQueue.getFullRemPathAt(0),
370 &fi, FT_ATTR_COPY_UPLOAD);
371 }
372 }
373 m_TransferQueue.deleteAt(0);
374 m_pFTDialog->postCheckTransferQueueMsg();
375 return true;
Dennis Syrovatsky8b194ee2005-11-10 08:56:34 +0000376}
377
378bool
379FileTransfer::procFLRDownload(FileInfo *pFI)
380{
381 return false;
382}
383
384bool
385FileTransfer::procFLRDelete(FileInfo *pFI)
386{
387 return false;
388}
389
390bool
391FileTransfer::procFLRRename(FileInfo *pFI)
392{
393 return false;
394}
395
396void
397FileTransfer::requestFileList(char *pPath, int dest, bool bDirOnly)
398{
399 m_queueFileListRqst.add(pPath, 0, 0, dest);
400
Dennis Syrovatskyf7b24492005-11-23 04:14:10 +0000401 m_pWriter->writeFileListRqst(strlen(pPath), pPath, bDirOnly);
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000402}
403
404int
405FileTransfer::isExistName(FileInfo *pFI, char *pName)
406{
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000407 for (unsigned int i = 0; i < pFI->getNumEntries(); i++) {
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000408 if (strcmp(pFI->getNameAt(i), pName) == 0) {
409 return i;
410 }
411 }
412 return -1;
413}
Dennis Syrovatsky29440e82005-12-05 09:31:28 +0000414
415void
416FileTransfer::freeQueues()
417{
418 m_TransferQueue.free();
419 m_DeleteQueue.free();
420}