void DownloadOperation::tryCalcInputFilesSize()
{
  FileInfoList *fil = m_toCopy;

  while (fil != NULL) {
    if (fil->getFileInfo()->isDirectory()) {
      StringStorage pathNoRoot;
      StringStorage pathToFile;

      fil->getAbsolutePath(&pathNoRoot, _T('/'));

      pathToFile.setString(m_pathToSourceRoot.getString());
      if (!pathToFile.endsWith(_T('/'))) {
        pathToFile.appendString(_T("/"));
      }
      pathToFile.appendString(pathNoRoot.getString());

      m_foldersToCalcSizeLeft++;
      m_sender->sendFolderSizeRequest(pathToFile.getString());
    } else {
      m_totalBytesToCopy += fil->getFileInfo()->getSize();
    }
    fil = fil->getNext();
  }
}
DesktopServerApplication::DesktopServerApplication(HINSTANCE appInstance, const TCHAR *commandLine)
: LocalWindowsApplication(appInstance),
  m_clToSrvChan(0),
  m_srvToClChan(0),
  m_clToSrvGate(0),
  m_srvToClGate(0),
  m_dispatcher(0),
  m_updHandlerSrv(0),
  m_uiSrv(0),
  m_cfgServer(0),
  m_gateKickHandler(0),
  m_sessionChangesWatcher(0)
{
  DesktopServerCommandLine cmdLineParser;

  cmdLineParser.parse(commandLine);

  DWORD baseSessionId = WTS::getActiveConsoleSessionId();

  StringStorage pathToLog;

  cmdLineParser.getLogDir(&pathToLog);

  if (!pathToLog.endsWith(_T('\\'))) {
    pathToLog.appendChar(_T('\\'));
  }
  pathToLog.appendString(_T("dtserver.log"));
  m_log = new FileLog(pathToLog.getString(), true);
  Configurator::getInstance()->addListener(this);

  m_log->changeLevel(cmdLineParser.getLogLevel());
  Log::message(_T("Log level has been changed to %d"),
               cmdLineParser.getLogLevel());

  try {
    StringStorage shMemName;
    cmdLineParser.getSharedMemName(&shMemName);
    SharedMemory shMem(shMemName.getString(), 72);
    UINT64 *mem = (UINT64 *)shMem.getMemPointer();
    HANDLE hWrite, hRead;

    DateTime startTime = DateTime::now();

    while (mem[0] == 0) {
      unsigned int timeForWait = max((int)10000 - 
                                     (int)(DateTime::now() -
                                           startTime).getTime(),
                                     0);
      if (timeForWait == 0) {
        throw Exception(_T("The desktop server time out expired"));
      }
    }

    hWrite = (HANDLE)mem[1];
    hRead  = (HANDLE)mem[2];
    m_clToSrvChan = new AnonymousPipe(hWrite, hRead);
    Log::info(_T("Client->server hWrite = %u; hRead = %u"), hWrite, hRead);

    hWrite = (HANDLE)mem[3];
    hRead  = (HANDLE)mem[4];
    m_srvToClChan = new AnonymousPipe(hWrite, hRead);
    Log::info(_T("Server->client hWrite = %u; hRead = %u"), hWrite, hRead);

    m_clToSrvGate = new BlockingGate(m_clToSrvChan);
    m_srvToClGate = new BlockingGate(m_srvToClChan);

    m_dispatcher = new DesktopSrvDispatcher(m_clToSrvGate, this);

    m_updHandlerSrv = new UpdateHandlerServer(m_srvToClGate, m_dispatcher, this);
    m_uiSrv = new UserInputServer(m_srvToClGate, m_dispatcher, this);
    m_cfgServer = new ConfigServer(m_dispatcher);
    m_gateKickHandler = new GateKickHandler(m_dispatcher);

    m_dispatcher->resume();

    m_sessionChangesWatcher = new SessionChangesWatcher(this);
  } catch (Exception &e) {
    Log::error(e.getMessage());
    freeResources();
    throw;
  }
}