1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include "commands.h"
42 #include <QtCore/QDebug>
43 #include <QtCore/QFileInfo>
44 #include <QtCore/QDir>
45 #include <QtCore/QProcess>
46 
47 #ifdef Q_OS_WINCE
48 #include <windows.h>
49 #endif
50 
51 /////////////////////////////////////////////////////
52 //       Abstract Command Implementation           //
53 /////////////////////////////////////////////////////
AbstractCommand()54 AbstractCommand::AbstractCommand()
55 : m_socket(0)
56 {
57 }
58 
~AbstractCommand()59 AbstractCommand::~AbstractCommand()
60 {
61 }
62 
reportSuccess()63 void AbstractCommand::reportSuccess()
64 {
65     m_socket->write(COMMAND_SUCCESS, strlen(COMMAND_SUCCESS));
66     m_socket->waitForBytesWritten();
67 }
68 
reportError()69 void AbstractCommand::reportError()
70 {
71     m_socket->write(COMMAND_ERROR, strlen(COMMAND_ERROR));
72     m_socket->waitForBytesWritten();
73 }
74 
dataReceived(QByteArray &)75 void AbstractCommand::dataReceived(QByteArray&)
76 {
77     debugOutput(1, "AbstractCommand::dataReceived NOT SUPPOSED TO BE HERE");
78 }
79 
commandFinished()80 void AbstractCommand::commandFinished()
81 {
82     debugOutput(1, "AbstractCommand::commandFinished()NOT SUPPOSED TO BE HERE");
83 }
84 
setSocket(QTcpSocket * socket)85 void AbstractCommand::setSocket(QTcpSocket* socket)
86 {
87     debugOutput(0, "AbstractCommand::setSocket()");
88     Q_ASSERT(socket);
89     m_socket = socket;
90     connect(m_socket, SIGNAL(readyRead()), this, SLOT(_readData()));
91     reportSuccess();
92 }
93 
socket()94 QTcpSocket* AbstractCommand::socket()
95 {
96     return m_socket;
97 }
98 
_readData()99 void AbstractCommand::_readData()
100 {
101     QByteArray arr = m_socket->readAll();
102     dataReceived(arr);
103 }
104 
_disconnect()105 void AbstractCommand::_disconnect()
106 {
107 }
108 
109 /////////////////////////////////////////////////////
110 //       Create File Command Implementation        //
111 /////////////////////////////////////////////////////
CreateFileCommand()112 CreateFileCommand::CreateFileCommand()
113 : m_dataCount(0)
114 {
115     debugOutput(0, "CreateFileCommand::CreateFileCommand");
116     m_options.fileSize= -1;
117 }
118 
~CreateFileCommand()119 CreateFileCommand::~CreateFileCommand()
120 {
121     debugOutput(0, "CreateFileCommand::~CreateFileCommand");
122     if (m_file.isOpen()) {
123         fprintf(stderr, "****************FILE IS STILL OPENED AND HAVENT FINISHED WRITING**********************\n");
124         fprintf(stderr, "Current: %d Expected: %d\n", m_dataCount , m_options.fileSize);
125         m_file.close();
126     }
127 }
128 
dataReceived(QByteArray & data)129 void CreateFileCommand::dataReceived(QByteArray &data)
130 {
131     bool successful = true;
132     // If we haven't received the options yet
133     if (m_options.fileSize == -1) {
134         CreateFileOptions* opt = (CreateFileOptions*) data.data();
135         memcpy(&m_options , opt , sizeof(CreateFileOptions));
136 
137         if (QFileInfo(QString::fromLatin1(m_options.fileName)).exists()) {
138             if (m_options.overwriteExisting) {
139 #ifdef Q_OS_WINCE
140                 SetFileAttributes(QFileInfo(m_options.fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL);
141 #endif
142                 QFile::remove(m_options.fileName);
143             } else
144                 successful = false;
145         }
146         m_file.setFileName(QString::fromLatin1(m_options.fileName));
147         if (!m_file.open(QIODevice::WriteOnly))
148             successful = false;
149         else
150             debugOutput(3, QString::fromLatin1("Creating file: %1").arg(m_options.fileName));
151     } else { // write buffer on disc
152         if (!m_file.isOpen())
153             return;
154         m_file.write(data);
155         m_dataCount += data.size();
156         if (m_dataCount >= m_options.fileSize) {
157             // We do not care about more data than announced
158             m_file.close();
159         }
160     }
161 
162     if (successful)
163         reportSuccess();
164     else
165         reportError();
166 }
167 
commandFinished()168 void CreateFileCommand::commandFinished()
169 {
170     debugOutput(0, "CreateFileCommand::commandFinished");
171 #ifdef Q_OS_WIN
172     // We need to set the file attributes for intelligent time comparisons
173     QString tmpFile = QString::fromLatin1(m_options.fileName);
174     HANDLE handle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
175     if (handle != INVALID_HANDLE_VALUE) {
176         SetFileTime(handle, &(m_options.fileTime), NULL, NULL);
177         CloseHandle(handle);
178     }
179     SetFileAttributes(tmpFile.utf16(), m_options.fileAttributes);
180 #endif
181 }
182 
183 /////////////////////////////////////////////////////
184 //    Create Directory Command Implementation      //
185 /////////////////////////////////////////////////////
CreateDirectoryCommand()186 CreateDirectoryCommand::CreateDirectoryCommand()
187         : AbstractCommand()
188 {
189     debugOutput(0, "CreateDirectoryCommand::CreateDirectoryCommand");
190 }
191 
~CreateDirectoryCommand()192 CreateDirectoryCommand::~CreateDirectoryCommand()
193 {
194     debugOutput(0, "CreateDirectoryCommand::~CreateDirectoryCommand()");
195 }
196 
dataReceived(QByteArray & data)197 void CreateDirectoryCommand::dataReceived(QByteArray &data)
198 {
199     debugOutput(0, "CreateDirectoryCommand::dataReceived()");
200     CreateDirectoryOptions* options = (CreateDirectoryOptions*) data.data();
201     debugOutput(3, QString::fromLatin1("Creating directory: %1").arg(options->dirName));
202     bool success = true;
203     QDir dir;
204     if (options->recursively)
205         success = dir.mkpath(options->dirName);
206     else
207         success = dir.mkdir(options->dirName);
208 
209     if (success)
210         reportSuccess();
211     else
212         reportError();
213 }
214 
commandFinished()215 void CreateDirectoryCommand::commandFinished()
216 {
217     debugOutput(0, "CreateDirectoryCommand::commandFinished()");
218 }
219 
220 /////////////////////////////////////////////////////
221 //        Copy File Command Implementation         //
222 /////////////////////////////////////////////////////
CopyFileCommand()223 CopyFileCommand::CopyFileCommand()
224         : AbstractCommand()
225 {
226     debugOutput(0, "CopyFileCommand::CopyFileCommand()");
227 }
228 
~CopyFileCommand()229 CopyFileCommand::~CopyFileCommand()
230 {
231     debugOutput(0, "CopyFileCommand::~CopyFileCommand()");
232 }
233 
dataReceived(QByteArray & data)234 void CopyFileCommand::dataReceived(QByteArray &data)
235 {
236     debugOutput(0, "CopyFileCommand::dataReceived()");
237     CopyFileOptions* options = (CopyFileOptions*) data.data();
238     debugOutput(3, QString::fromLatin1("Copy File: %1 ->  %2").arg(options->from).arg(options->to));
239     bool success = true;
240     if (QFileInfo(options->to).exists()) {
241         if (options->overwriteExisting)
242             QFile::remove(options->to);
243         else
244             success = false;
245     }
246     if (success)
247         if (!QFile::copy(options->from , options->to))
248             success = false;
249 
250     if (success)
251         reportSuccess();
252     else
253         reportError();
254 }
255 
commandFinished()256 void CopyFileCommand::commandFinished()
257 {
258     debugOutput(0, "CopyFileCommand::commandFinished()");
259 }
260 
261 /////////////////////////////////////////////////////
262 //      Copy Directory Command Implementation      //
263 /////////////////////////////////////////////////////
CopyDirectoryCommand()264 CopyDirectoryCommand::CopyDirectoryCommand()
265         : AbstractCommand()
266 {
267     debugOutput(0, "CopyDirectoryCommand::CopyDirectoryCommand()");
268 }
269 
~CopyDirectoryCommand()270 CopyDirectoryCommand::~CopyDirectoryCommand()
271 {
272     debugOutput(0, "CopyDirectoryCommand::~CopyDirectoryCommand()");
273 }
274 
dataReceived(QByteArray & data)275 void CopyDirectoryCommand::dataReceived(QByteArray &data)
276 {
277     debugOutput(0, "CopyDirectoryCommand::dataReceived()");
278     CopyDirectoryOptions* options = (CopyDirectoryOptions*) data.data();
279     debugOutput(3, QString::fromLatin1("Copy Directory: %1 %2").arg(options->from).arg(options->to));
280     if (copyDir(QLatin1String(options->from) , QLatin1String(options->to) , options->recursive))
281         reportSuccess();
282     else
283         reportError();
284 }
285 
commandFinished()286 void CopyDirectoryCommand::commandFinished()
287 {
288     debugOutput(0, "CopyDirectoryCommand::commandFinished()");
289 }
290 
copyDir(const QString & from,const QString & to,bool recursive)291 bool CopyDirectoryCommand::copyDir(const QString &from, const QString &to, bool recursive)
292 {
293     QDir().mkpath(to);
294     QDir sourceDir(from);
295     QDir destDir(to);
296     QStringList entries = sourceDir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
297     foreach (QString item , entries) {
298         QString itemFrom = sourceDir.absoluteFilePath(item);
299         QString itemTo = destDir.absoluteFilePath(item);
300         if (QFileInfo(item).isDir()) {
301             if (recursive && !copyDir(itemFrom, itemTo, recursive))
302                 return false;
303         } else {
304             if (!QFile::copy(itemFrom, itemTo))
305                 return false;
306         }
307     }
308     return true;
309 }
310 
311 /////////////////////////////////////////////////////
312 //        Delete File Command Implementation       //
313 /////////////////////////////////////////////////////
DeleteFileCommand()314 DeleteFileCommand::DeleteFileCommand()
315         : AbstractCommand()
316 {
317     debugOutput(0, "DeleteFileCommand::DeleteFileCommand()");
318 }
319 
~DeleteFileCommand()320 DeleteFileCommand::~DeleteFileCommand()
321 {
322     debugOutput(0, "DeleteFileCommand::~DeleteFileCommand()");
323 }
324 
dataReceived(QByteArray & data)325 void DeleteFileCommand::dataReceived(QByteArray &data)
326 {
327     debugOutput(0, "DeleteFileCommand::dataReceived()");
328     DeleteFileOptions* options = (DeleteFileOptions*) data.data();
329     debugOutput(3, QString::fromLatin1("Delete File: %1").arg(options->fileName));
330     bool success = true;
331     QFile file(options->fileName);
332     if (file.exists()) {
333 #ifdef Q_OS_WINCE
334         SetFileAttributes(QFileInfo(options->fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL);
335 #endif
336         success = file.remove();
337     } else
338         success = false;
339 
340     if (success)
341         reportSuccess();
342     else
343         reportError();
344 }
345 
commandFinished()346 void DeleteFileCommand::commandFinished()
347 {
348     debugOutput(0, "DeleteFileCommand::commandFinished()");
349 }
350 
351 /////////////////////////////////////////////////////
352 //     Delete Directory Command Implementation     //
353 /////////////////////////////////////////////////////
DeleteDirectoryCommand()354 DeleteDirectoryCommand::DeleteDirectoryCommand()
355         : AbstractCommand()
356 {
357     debugOutput(0, "DeleteDirectoryCommand::DeleteDirectoryCommand()");
358 }
359 
~DeleteDirectoryCommand()360 DeleteDirectoryCommand::~DeleteDirectoryCommand()
361 {
362     debugOutput(0, "DeleteDirectoryCommand::~DeleteDirectoryCommand()");
363 }
364 
dataReceived(QByteArray & data)365 void DeleteDirectoryCommand::dataReceived(QByteArray &data)
366 {
367     debugOutput(0, "DeleteDirectoryCommand::dataReceived()");
368     DeleteDirectoryOptions* options = (DeleteDirectoryOptions*) data.data();
369     debugOutput(3, QString::fromLatin1("Delete directory: %1").arg(options->dirName));
370     if (deleteDirectory(QLatin1String(options->dirName), options->recursive, options->failIfContentExists))
371         reportSuccess();
372     else
373         reportError();
374 }
375 
commandFinished()376 void DeleteDirectoryCommand::commandFinished()
377 {
378     debugOutput(0, "DeleteDirectoryCommand::commandFinished()");
379 }
380 
deleteDirectory(const QString & dirName,bool recursive,bool failIfContentExists)381 bool DeleteDirectoryCommand::deleteDirectory(const QString &dirName, bool recursive, bool failIfContentExists)
382 {
383     QDir dir(dirName);
384     if (!dir.exists())
385         return false;
386 
387     QStringList itemList = dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
388     if (itemList.size() > 0 && failIfContentExists)
389         return false;
390 
391     foreach (QString item, itemList) {
392         QString itemName = dir.absoluteFilePath(item);
393         if (QFileInfo(itemName).isDir()) {
394             if (recursive && !deleteDirectory(itemName, recursive, failIfContentExists))
395                 return false;
396         } else {
397             if (!dir.remove(item))
398                 return false;
399         }
400     }
401     QString lastName = dir.dirName();
402     dir.cdUp();
403     dir.rmpath(lastName);
404     return true;
405 }
406 
407 /////////////////////////////////////////////////////
408 //         Execute Command Implementation          //
409 /////////////////////////////////////////////////////
ExecuteCommand()410 ExecuteCommand::ExecuteCommand()
411         : AbstractCommand()
412         , m_argumentCount(0)
413         , m_timeout(-1)
414 {
415     debugOutput(0, "ExecuteCommand::ExecuteCommand()");
416 }
417 
~ExecuteCommand()418 ExecuteCommand::~ExecuteCommand()
419 {
420     debugOutput(0, "ExecuteCommand::~ExecuteCommand()");
421 }
422 
dataReceived(QByteArray & data)423 void ExecuteCommand::dataReceived(QByteArray &data)
424 {
425     debugOutput(0, "ExecuteCommand::dataReceived()");
426 
427     if (m_argumentCount == 0) {
428         ExecuteOptions* options = (ExecuteOptions*) data.data();
429         if (!QFileInfo(options->appName).exists()) {
430             debugOutput(1, "Error execute: application does not exist");
431             reportError();
432             return;
433         }
434 
435         m_program = QLatin1String(options->appName);
436         m_argumentCount = options->argumentsCount;
437         m_waitFinished = options->waitForFinished;
438         m_timeout = options->timeout;
439         if (m_argumentCount == 0)
440             m_argumentCount = -1; // to trigger startup on next receive
441         reportSuccess();
442     } else if (m_arguments.size() < m_argumentCount) {
443         m_arguments += data;
444         reportSuccess();
445     } else { // do the execution
446         if (data == COMMAND_SUCCESS)
447             _doExecute();
448     }
449 }
450 
_doExecute()451 void ExecuteCommand::_doExecute()
452 {
453     debugOutput(0, "ExecuteCommand::_doExecute()");
454     debugOutput(3, QString::fromLatin1("Execute: %1 %2").arg(m_program).arg(m_arguments.join(" ")));
455     if (m_waitFinished) {
456         QProcess process;
457         process.start(m_program, m_arguments);
458         if (process.waitForFinished(m_timeout) == false || process.exitCode() < 0)
459             reportError();
460         else
461             reportSuccess();
462     } else {
463         if (QProcess::startDetached(m_program, m_arguments))
464             reportSuccess();
465         else
466             reportError();
467     }
468 }
commandFinished()469 void ExecuteCommand::commandFinished()
470 {
471     debugOutput(0,"ExecuteCommand::commandFinished()");
472 }
473 
474 /////////////////////////////////////////////////////
475 //           Read File Implementation              //
476 /////////////////////////////////////////////////////
ReadFileCommand()477 ReadFileCommand::ReadFileCommand()
478         : AbstractCommand()
479         , m_currentPos(0)
480 {
481     debugOutput(0, "ReadFileCommand::ReadFileCommand()");
482     m_fileName.clear();
483 }
484 
~ReadFileCommand()485 ReadFileCommand::~ReadFileCommand()
486 {
487     debugOutput(0, "ReadFileCommand::~ReadFileCommand()");
488     if (m_file.isOpen())
489         m_file.close();
490 }
491 
dataReceived(QByteArray & data)492 void ReadFileCommand::dataReceived(QByteArray &data)
493 {
494     debugOutput(0, "ReadFileCommand::dataReceived()");
495     if (m_fileName.isEmpty()) {
496         ReadFileOptions* option = (ReadFileOptions*) data.data();
497         m_fileName = QLatin1String(option->fileName);
498         QFileInfo info(m_fileName);
499         m_file.setFileName(m_fileName);
500         ReadFileReply reply;
501         if (!info.exists() || !info.isFile() || !m_file.open(QIODevice::ReadOnly))
502             reply.fileValid = false;
503         else
504             reply.fileValid = true;
505         reply.fileSize = info.size();
506         m_fileSize = reply.fileSize;
507         socket()->write((char*) &reply, sizeof(reply));
508         debugOutput(3, QString::fromLatin1("Reading file: %1").arg(m_fileName));
509     } else {
510         QTcpSocket* sock = socket(); // design failure???
511         if (data != COMMAND_SUCCESS || m_currentPos >= m_fileSize) {
512             sock->disconnectFromHost();
513             return;
514         }
515         const int bufferSize = 1024;
516         QByteArray buffer = m_file.read(bufferSize);
517         m_currentPos += buffer.size();
518         sock->write(buffer);
519         sock->waitForBytesWritten();
520     }
521 }
522 
commandFinished()523 void ReadFileCommand::commandFinished()
524 {
525     debugOutput(0, "ReadFileCommand::commandFinished()");
526 }
527 
528 /////////////////////////////////////////////////////
529 //        Read Directory Implementation            //
530 /////////////////////////////////////////////////////
ReadDirectoryCommand()531 ReadDirectoryCommand::ReadDirectoryCommand()
532         : AbstractCommand()
533         , m_iterator(0)
534 {
535     debugOutput(0, "ReadDirectoryCommand::ReadDirectoryCommand");
536     m_dirName.clear();
537 }
538 
~ReadDirectoryCommand()539 ReadDirectoryCommand::~ReadDirectoryCommand()
540 {
541     debugOutput(0, "ReadDirectoryCommand::~ReadDirectoryCommand()");
542     delete m_iterator;
543 }
544 
dataReceived(QByteArray & data)545 void ReadDirectoryCommand::dataReceived(QByteArray &data)
546 {
547     debugOutput(0, "ReadDirectoryCommand::dataReceived()");
548     QTcpSocket* sock = socket();
549     if (m_dirName.isEmpty()) {
550         ReadDirectoryOptions* option = (ReadDirectoryOptions*) data.data();
551         QFileInfo info(QLatin1String(option->dirName));
552         debugOutput(3, QString::fromLatin1("Reading Directory entries: %1").arg(option->dirName));
553         ReadDirectoryReply reply;
554         if (!info.exists() || !info.isDir()) {
555             reply.itemCount = -1;
556             reply.entryValid = false;
557         } else {
558             m_dirName = QLatin1String(option->dirName);
559             m_dir.setPath(m_dirName);
560             m_iterator = new QDirIterator(m_dir);
561             reply.itemCount = m_dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).size();
562             reply.entryValid = true;
563         }
564         sock->write((char*) &reply, sizeof(reply));
565         sock->waitForBytesWritten();
566     } else {
567         if (data != COMMAND_SUCCESS) {
568             qDebug() << "Something went wrong in the meantime";
569             return;
570         }
571         ReadDirectoryItem reply;
572         if (m_iterator->hasNext()) {
573             m_iterator->next();
574             QFileInfo info = m_iterator->fileInfo();
575             strcpy(reply.name, qPrintable(info.absoluteFilePath()));
576             reply.isDirectory = info.isDir();
577             if (!reply.isDirectory)
578                 reply.size = info.size();
579         }
580         reply.hasMore = m_iterator->hasNext();
581         sock->write((char*) &reply, sizeof(reply));
582         sock->waitForBytesWritten();
583     }
584 }
585 
commandFinished()586 void ReadDirectoryCommand::commandFinished()
587 {
588     debugOutput(0, "ReadDirectoryCommand::commandFinished()");
589 }
590 
591 /////////////////////////////////////////////////////
592 //           File Time Implementation              //
593 /////////////////////////////////////////////////////
FileTimeCommand()594 FileTimeCommand::FileTimeCommand()
595         : AbstractCommand()
596 {
597     debugOutput(0, "FileTimeCommand::FileTimeCommand()");
598 }
599 
~FileTimeCommand()600 FileTimeCommand::~FileTimeCommand()
601 {
602     debugOutput(0, "FileTimeCommand::~FileTimeCommand()");
603 }
604 
dataReceived(QByteArray & data)605 void FileTimeCommand::dataReceived(QByteArray &data)
606 {
607     debugOutput(0, "FileTimeCommand::dataReceived()");
608     FileTimeOptions* option = (FileTimeOptions*) data.data();
609 
610     FILETIME resultTime;
611     resultTime.dwLowDateTime = -1;
612     resultTime.dwHighDateTime = -1;
613 
614 #ifdef Q_OS_WIN
615     QString fileName = QLatin1String(option->fileName);
616     HANDLE deviceHandle = CreateFile(fileName.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
617     debugOutput(3, QString::fromLatin1("Asking FileTime: %1").arg(fileName));
618     if (deviceHandle != INVALID_HANDLE_VALUE) {
619         FILETIME deviceCreationTime;
620         if (GetFileTime(deviceHandle, &deviceCreationTime, NULL, NULL)) {
621             resultTime = deviceCreationTime;
622         }
623         CloseHandle(deviceHandle);
624     }
625 #endif
626     QTcpSocket* sock = socket();
627     sock->write((char*) &resultTime, sizeof(resultTime));
628     sock->waitForBytesWritten();
629 }
630 
commandFinished()631 void FileTimeCommand::commandFinished()
632 {
633     debugOutput(0, "FileTimeCommand::commandFinished()");
634 }
635 
636 /////////////////////////////////////////////////////
637 //           Time Stamp Implementation             //
638 /////////////////////////////////////////////////////
TimeStampCommand()639 TimeStampCommand::TimeStampCommand()
640         : AbstractCommand()
641 {
642     debugOutput(0, "TimeStampCommand::TimeStampCommand()");
643 }
644 
~TimeStampCommand()645 TimeStampCommand::~TimeStampCommand()
646 {
647     debugOutput(0, "TimeStampCommand::~TimeStampCommand()");
648 }
649 
dataReceived(QByteArray & data)650 void TimeStampCommand::dataReceived(QByteArray &data)
651 {
652     debugOutput(0, "TimeStampCommand::dataReceived()");
653     FILETIME resultTime;
654     resultTime.dwLowDateTime = -1;
655     resultTime.dwHighDateTime = -1;
656 
657 #ifdef Q_OS_WIN
658     FILETIME stampTime = *((FILETIME*)data.data());
659 
660     QString tmpFile = QString::fromLatin1("\\qt_tmp_ftime_convert");
661     HANDLE remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
662     if (remoteHandle != INVALID_HANDLE_VALUE) {
663         if (!SetFileTime(remoteHandle, &stampTime, NULL, NULL)) {
664             CloseHandle(remoteHandle);
665         } else {
666             CloseHandle(remoteHandle);
667             remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
668             if (remoteHandle != INVALID_HANDLE_VALUE) {
669                 if (GetFileTime(remoteHandle, &stampTime, NULL, NULL))
670                     resultTime = stampTime;
671                 CloseHandle(remoteHandle);
672                 DeleteFile(tmpFile.utf16());
673             }
674         }
675     }
676     debugOutput(3, QString::fromLatin1("Asking TimeStamp"));
677 #endif
678     QTcpSocket* sock = socket();
679     sock->write((char*) &resultTime, sizeof(resultTime));
680     sock->waitForBytesWritten();
681 }
682 
commandFinished()683 void TimeStampCommand::commandFinished()
684 {
685     debugOutput(0, "TimeStampCommand::commandFinished()");
686 }
687