blob: fe08dd8e6c84a34acc4e95377885e3ca5af951b1 [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 }
49}
Dennis Syrovatsky139d7832005-11-02 05:36:05 +000050
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000051bool
52FileTransfer::initialize(rdr::InStream *pIS, rdr::OutStream *pOS)
53{
54 if (m_bInitialized) return false;
55
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000056 m_pReader = new FTMsgReader(pIS);
57 m_pWriter = new FTMsgWriter(pOS);
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000058
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +000059 m_TransferQueue.free();
60
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000061 m_bInitialized = true;
62 return true;
63}
64
65bool
Dennis Syrovatsky4905c8f2005-11-21 15:52:46 +000066FileTransfer::show(HWND hwndParent)
Dennis Syrovatsky4ab41852005-11-07 09:52:36 +000067{
Dennis Syrovatskyda17d212005-11-09 05:58:30 +000068 if (!m_bInitialized) return false;
69
Dennis Syrovatsky4905c8f2005-11-21 15:52:46 +000070 m_bFTDlgShown = m_pFTDialog->createFTDialog(hwndParent);
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +000071
Dennis Syrovatsky5c761172005-11-09 04:19:05 +000072 return m_bFTDlgShown;
Dennis Syrovatsky139d7832005-11-02 05:36:05 +000073}
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000074
75bool
76FileTransfer::processFTMsg(int type)
77{
Dennis Syrovatsky514555b2005-11-21 14:40:56 +000078 if (!m_bInitialized) return false;
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000079
80 switch (type)
81 {
82 case msgTypeFileListData:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000083 return procFileListDataMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000084 case msgTypeFileDownloadData:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000085 return procFileDownloadDataMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000086 case msgTypeFileUploadCancel:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000087 return procFileUploadCancelMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000088 case msgTypeFileDownloadFailed:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000089 return procFileDownloadFailedMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000090 case msgTypeFileDirSizeData:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000091 return procFileDirSizeDataMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000092 case msgTypeFileLastRequestFailed:
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000093 return procFileLastRqstFailedMsg();
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000094 default:
95 return false;
96 }
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000097}
Dennis Syrovatsky63943a32005-11-10 06:24:56 +000098
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +000099bool
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000100FileTransfer::isTransferEnable()
101{
102 if (m_TransferQueue.getNumEntries() > 0) return true; else return false;
103}
104
105void
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000106FileTransfer::addTransferQueue(char *pLocalPath, char *pRemotePath,
107 FileInfo *pFI, unsigned int flags)
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000108{
109 if ((m_bFTDlgShown) && (!isTransferEnable())) m_pFTDialog->setStatusText("Starting Copy Operation");
110
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000111 m_TransferQueue.add(pLocalPath, pRemotePath, pFI, (flags | FT_ATTR_RESIZE_NEEDED));
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000112
113 checkTransferQueue();
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000114}
115
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000116bool
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000117FileTransfer::resizeSending()
118{
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000119 for (unsigned int i = 0; i < m_TransferQueue.getNumEntries(); i++) {
120 unsigned int flags = m_TransferQueue.getFlagsAt(i);
121 if (flags & FT_ATTR_RESIZE_NEEDED) {
122 if (flags & FT_ATTR_FILE) {
123 m_dw64SizeSending += m_TransferQueue.getSizeAt(i);
124 m_TransferQueue.clearFlagAt(i, FT_ATTR_RESIZE_NEEDED);
125 } else {
126 if (flags & FT_ATTR_DIR) {
127 if (flags & FT_ATTR_COPY_DOWNLOAD) {
128 char *pPath = m_TransferQueue.getFullRemPathAt(i);
129 m_dirSizeRqstNum = i;
130 m_pWriter->writeFileDirSizeRqst(strlen(pPath), pPath);
131 return false;
132 } else {
133 if (flags & FT_ATTR_COPY_UPLOAD) {
134 FolderManager fm;
135 DWORD64 dw64Size;
136 fm.getDirSize(m_TransferQueue.getFullLocPathAt(i), &dw64Size);
137 m_dw64SizeSending += dw64Size;
138 m_TransferQueue.clearFlagAt(i, FT_ATTR_RESIZE_NEEDED);
139 }
140 } // if (flags & FT_ATTR_COPY_DOWNLOAD)
141 } // if (flags & FT_ATTR_FOLDER)
142 } // if (flags & FT_ATTR_FILE)
143 } // if (flags & FT_ATTR_NEEDED_RESIZE)
144 } // for (unsigned int i = 0; i < m_TransferQueue.getNumEntries(); i++)
145 return true;
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000146}
147
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000148void
149FileTransfer::checkTransferQueue()
150{
151 if (!isTransferEnable()) {
152 if (m_bFTDlgShown) {
153 m_pFTDialog->setStatusText("File Transfer Operation Completed Successfully");
154 PostMessage(m_pFTDialog->getWndHandle(), WM_COMMAND, MAKEWPARAM(IDC_FTLOCALRELOAD, 0), 0);
155 PostMessage(m_pFTDialog->getWndHandle(), WM_COMMAND, MAKEWPARAM(IDC_FTREMOTERELOAD, 0), 0);
156 return;
157 }
158 } else {
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000159 if (!resizeSending()) return;
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000160
161 unsigned int flag0 = m_TransferQueue.getFlagsAt(0);
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000162
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000163 if (flag0 & FT_ATTR_COPY_UPLOAD) {
164 if (flag0 & FT_ATTR_FILE) {
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000165 uploadFile();
166 return;
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000167 }
168 if (flag0 & FT_ATTR_DIR) {
169 char *pFullPath = m_TransferQueue.getFullRemPathAt(0);
170 if (m_bFTDlgShown) m_pFTDialog->setStatusText("Creating Remote Folder. %s", pFullPath);
171 m_pWriter->writeFileCreateDirRqst(strlen(pFullPath), pFullPath);
172
173 char *pPath = m_TransferQueue.getRemPathAt(0);
174 m_TransferQueue.setFlagsAt(0, (flag0 | FT_ATTR_FLR_UPLOAD_CHECK));
175 m_queueFileListRqst.add(pPath, 0, 0, FT_FLR_DEST_UPLOAD);
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000176 m_pWriter->writeFileListRqst(strlen(pPath), pPath, false);
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000177 return;
178 }
179 } else {
180 if (flag0 & FT_ATTR_COPY_DOWNLOAD) {
181 if (flag0 & FT_ATTR_FILE) {
182 }
183 if (flag0 & FT_ATTR_DIR) {
184 }
185 }
186 }
187 if (m_bFTDlgShown) m_pFTDialog->setStatusText("File Transfer Operation Failed. Unknown data in the transfer queue");
188
189 } // if (!isTransferEnable())
190}
191
192bool
193FileTransfer::uploadFile()
194{
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000195 if (m_TransferQueue.getFlagsAt(0) & FT_ATTR_FILE) {
196 if (m_fileReader.create(m_TransferQueue.getFullLocPathAt(0))) {
197 m_pWriter->writeFileUploadRqst(strlen(m_TransferQueue.getFullRemPathAt(0)),
198 m_TransferQueue.getFullRemPathAt(0), 0);
199 uploadFilePortion();
200 }
201 }
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000202 return false;
203}
204
205bool
206FileTransfer::downloadFile()
207{
208 return false;
209}
210
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000211void
212FileTransfer::uploadFilePortion()
213{
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000214 if (m_fileReader.isCreated()) {
215 char buf[FT_MAX_SENDING_SIZE];
216 unsigned int bytesRead = 0;
217 if (m_fileReader.read((void *)buf, FT_MAX_SENDING_SIZE, &bytesRead)) {
218 if (bytesRead == 0) {
219 m_pWriter->writeFileUploadData(m_TransferQueue.getDataAt(0));
220 m_fileReader.close();
221 m_TransferQueue.deleteAt(0);
222 m_pFTDialog->postCheckTransferQueueMsg();
223 } else {
224 m_pWriter->writeFileUploadData(bytesRead, (char *)buf);
225 m_pFTDialog->postUploadFilePortionMsg();
226 }
227 } else {
228 m_fileReader.close();
229 m_TransferQueue.deleteAt(0);
230 m_pFTDialog->postCheckTransferQueueMsg();
231 }
232 }
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000233}
234
235void
236FileTransfer::downloadFilePortion()
237{
238
239}
240
Dennis Syrovatsky6806fec2005-11-28 06:12:44 +0000241bool
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +0000242FileTransfer::procFileListDataMsg()
243{
Dennis Syrovatsky8b194ee2005-11-10 08:56:34 +0000244 FileInfo fileInfo;
245 int res = m_pReader->readFileListData(&fileInfo);
246
247 bool bResult;
248 switch (m_queueFileListRqst.getFlagsAt(0))
249 {
250 case FT_FLR_DEST_MAIN:
251 if (!m_bFTDlgShown) break;
252
253 if (res < 0) {
254 m_pFTDialog->reqFolderUnavailable();
255 bResult = true;
256 } else {
257 bResult = procFLRMain(&fileInfo);
258 }
259 break;
260 case FT_FLR_DEST_BROWSE:
261 bResult = procFLRBrowse(&fileInfo);
262 break;
263 case FT_FLR_DEST_UPLOAD:
264 bResult = procFLRUpload(&fileInfo);
265 break;
266 case FT_FLR_DEST_DOWNLOAD:
267 bResult = procFLRDownload(&fileInfo);
268 break;
269 case FT_FLR_DEST_DELETE:
270 bResult = procFLRDelete(&fileInfo);
271 break;
272 case FT_FLR_DEST_RENAME:
273 bResult = procFLRRename(&fileInfo);
274 break;
275 }
276 m_queueFileListRqst.deleteAt(0);
277 return bResult;
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +0000278}
279
280bool
281FileTransfer::procFileDownloadDataMsg()
282{
283 return false;
284}
285
286bool
287FileTransfer::procFileUploadCancelMsg()
288{
289 return false;
290}
291
292bool
293FileTransfer::procFileDownloadFailedMsg()
294{
295 return false;
296}
297
298bool
299FileTransfer::procFileDirSizeDataMsg()
300{
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000301 DWORD64 dw64DirSize = 0;
302 m_pReader->readFileDirSizeData(&dw64DirSize);
303 m_TransferQueue.clearFlagAt(m_dirSizeRqstNum, FT_ATTR_RESIZE_NEEDED);
Dennis Syrovatsky13b4d4c2005-11-28 08:14:18 +0000304 checkTransferQueue();
Dennis Syrovatskyc4ed9b72005-11-28 07:10:27 +0000305 return true;
Dennis Syrovatskyc08f0422005-11-10 06:36:46 +0000306}
307
308bool
309FileTransfer::procFileLastRqstFailedMsg()
310{
311 return false;
312}
Dennis Syrovatsky8b194ee2005-11-10 08:56:34 +0000313
314bool
315FileTransfer::procFLRMain(FileInfo *pFI)
316{
317 if (m_bFTDlgShown) m_pFTDialog->addRemoteLVItems(pFI);
318 return true;
319}
320
321bool
322FileTransfer::procFLRBrowse(FileInfo *pFI)
323{
324 return false;
325}
326
327bool
328FileTransfer::procFLRUpload(FileInfo *pFI)
329{
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000330 unsigned int flags = m_TransferQueue.getFlagsAt(0);
331 if (flags & FT_ATTR_FLR_UPLOAD_CHECK) {
332 int num = isExistName(pFI, m_TransferQueue.getRemNameAt(0));
333 if (num >= 0) {
334 if ((m_bFTDlgShown) && (strcmp(m_TransferQueue.getRemPathAt(0), m_pFTDialog->getRemotePath()) == 0)) {
335 m_pFTDialog->addRemoteLVItems(pFI);
336 }
337 } else {
338 if (flags & FT_ATTR_DIR) {
339 m_TransferQueue.deleteAt(0);
340 if (m_bFTDlgShown) m_pFTDialog->setStatusText("Create Remote Folder Failed.");
341 }
342 }
343 }
344 FolderManager fm;
345 FileInfo fi;
346 flags = m_TransferQueue.getFlagsAt(0);
347 if (flags & FT_ATTR_FILE) {
348 uploadFile();
349 return true;
350 } else {
351 if (fm.getDirInfo(m_TransferQueue.getFullLocPathAt(0), &fi, 0)) {
352 m_TransferQueue.add(m_TransferQueue.getFullLocPathAt(0),
353 m_TransferQueue.getFullRemPathAt(0),
354 &fi, FT_ATTR_COPY_UPLOAD);
355 }
356 }
357 m_TransferQueue.deleteAt(0);
358 m_pFTDialog->postCheckTransferQueueMsg();
359 return true;
Dennis Syrovatsky8b194ee2005-11-10 08:56:34 +0000360}
361
362bool
363FileTransfer::procFLRDownload(FileInfo *pFI)
364{
365 return false;
366}
367
368bool
369FileTransfer::procFLRDelete(FileInfo *pFI)
370{
371 return false;
372}
373
374bool
375FileTransfer::procFLRRename(FileInfo *pFI)
376{
377 return false;
378}
379
380void
381FileTransfer::requestFileList(char *pPath, int dest, bool bDirOnly)
382{
383 m_queueFileListRqst.add(pPath, 0, 0, dest);
384
Dennis Syrovatskyf7b24492005-11-23 04:14:10 +0000385 m_pWriter->writeFileListRqst(strlen(pPath), pPath, bDirOnly);
Dennis Syrovatsky5ae73f12005-11-30 04:15:40 +0000386}
387
388int
389FileTransfer::isExistName(FileInfo *pFI, char *pName)
390{
391 for (int i = 0; i < pFI->getNumEntries(); i++) {
392 if (strcmp(pFI->getNameAt(i), pName) == 0) {
393 return i;
394 }
395 }
396 return -1;
397}