mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Squashed commit of the following:
commit 4d9b072f560fa171a1390b7c74425614aa20e955
Author: Olivier Goffart <ogoffart@woboq.com>
Date: Tue Oct 14 16:04:02 2014 +0200
Remove useless variable
commit 8e85de0307ec5f31bf3f92a7de793fed7d41c2ea
Author: Daniel Molkentin <danimo@owncloud.com>
Date: Tue Oct 14 16:01:52 2014 +0200
Make Windows Explorer Extension build
commit 8e2942cd9fd32e3af72d60cba0d06bd9d6222a45
Author: Daniel Molkentin <danimo@owncloud.com>
Date: Tue Oct 14 11:39:37 2014 +0200
Fix compilation
commit 0fc0c0e0e0c7e58ad97f62700256c7d1f8c0670b
Author: Olivier Goffart <ogoffart@woboq.com>
Date: Tue Oct 14 11:48:32 2014 +0200
Windows Shell Integration: Try to let the thread notify about changes when there are changes
commit 4a1712b7c03269ca3007f167b8f313ea47655967
Author: Olivier Goffart <ogoffart@woboq.com>
Date: Tue Oct 14 11:35:20 2014 +0200
Windows Shell Integration: Share the RemotePathChecker amongst all the OCOverlay instances
commit 2d87408e9af5a4d7ab71c460ce606ba1f367c09f
Author: Olivier Goffart <ogoffart@woboq.com>
Date: Mon Oct 13 18:55:15 2014 +0200
Windows Shell Integration: Attempts to wait on multiple objects (WIP)
commit e448e427b6d1561ad7a40d08fc6632f4d2b4ef44
Author: Daniel Molkentin <danimo@owncloud.com>
Date: Mon Oct 13 17:58:02 2014 +0200
Introduce a worker thread
commit 2344407ec0bc1ce173ebbacadcf3992d62d94078
Author: Olivier Goffart <ogoffart@woboq.com>
Date: Mon Oct 13 17:03:47 2014 +0200
Windows Shell Integration: try to keep the socket open using a thread (WIP)
commit ea6d5273ed60d8bc3f1c5d5c6936364d783a1c0f
Author: Daniel Molkentin <danimo@owncloud.com>
Date: Mon Oct 13 15:27:46 2014 +0200
Make Explorer plugin work again with named pipes
This is a temporary hack, which needs more refactoring.
commit 44a3437a44082379efa0078c9afd7b8bbde930de
Author: Daniel Molkentin <danimo@owncloud.com>
Date: Sat Oct 11 07:31:24 2014 +0200
Fix code
commit 123390a0f3516c0078309d7048c6d2acb9293676
Author: Olivier Goffart <ogoffart@woboq.com>
Date: Fri Oct 10 16:29:35 2014 +0200
Windows shell integration: Use named pipe (WIP)
commit 9eea7e2321abeac6b8db0bd85bfce612dbf6bb20
Author: Olivier Goffart <ogoffart@woboq.com>
Date: Wed Oct 1 12:04:13 2014 +0200
Windows Shell Integration: Simplify StringUtil
This fixes a memory leak in CommunicationSocket::ReadLine
159 lines
4.4 KiB
C++
159 lines
4.4 KiB
C++
/**
|
|
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU Lesser General Public License as published by the Free
|
|
* Software Foundation; version 2.1 of the License
|
|
*
|
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*/
|
|
|
|
#include "CommunicationSocket.h"
|
|
|
|
#include "RemotePathChecker.h"
|
|
#include "StringUtil.h"
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <iterator>
|
|
#include <unordered_set>
|
|
#include <cassert>
|
|
|
|
#include <shlobj.h>
|
|
|
|
using namespace std;
|
|
|
|
|
|
// This code is run in a thread
|
|
void RemotePathChecker::workerThreadLoop()
|
|
{
|
|
CommunicationSocket socket;
|
|
std::unordered_set<std::wstring> asked;
|
|
if (!socket.Connect()) {
|
|
return;
|
|
//FIXME! what if this fails! what if we are disconnected later?
|
|
}
|
|
|
|
while(!_stop) {
|
|
{
|
|
std::unique_lock<std::mutex> lock(_mutex);
|
|
while (!_pending.empty() && !_stop) {
|
|
auto filePath = _pending.front();
|
|
_pending.pop();
|
|
|
|
lock.unlock();
|
|
if (!asked.count(filePath)) {
|
|
asked.insert(filePath);
|
|
socket.SendMsg(wstring(L"RETRIEVE_FILE_STATUS:" + filePath + L'\n').data());
|
|
}
|
|
lock.lock();
|
|
}
|
|
}
|
|
|
|
std::wstring response;
|
|
while (!_stop && socket.ReadLine(&response)) {
|
|
if (StringUtil::begins_with(response, wstring(L"REGISTER_PATH:"))) {
|
|
wstring responsePath = response.substr(14); // length of REGISTER_PATH:
|
|
|
|
std::unique_lock<std::mutex> lock(_mutex);
|
|
_watchedDirectories.push_back(responsePath);
|
|
} else if (StringUtil::begins_with(response, wstring(L"STATUS:")) ||
|
|
StringUtil::begins_with(response, wstring(L"BROADCAST:"))) {
|
|
|
|
auto statusBegin = response.find(L':', 0);
|
|
assert(statusBegin != std::wstring::npos);
|
|
|
|
auto statusEnd = response.find(L':', statusBegin + 1);
|
|
if (statusEnd == std::wstring::npos) {
|
|
// the command do not contains two colon?
|
|
continue;
|
|
}
|
|
|
|
auto responseStatus = response.substr(statusBegin+1, statusEnd - statusBegin-1);
|
|
auto responsePath = response.substr(statusEnd+1);
|
|
auto state = _StrToFileState(responseStatus);
|
|
auto erased = asked.erase(responsePath);
|
|
|
|
{ std::unique_lock<std::mutex> lock(_mutex);
|
|
_cache[responsePath] = state;
|
|
}
|
|
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATH, responsePath.data(), NULL);
|
|
}
|
|
}
|
|
|
|
if (_stop)
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
RemotePathChecker::RemotePathChecker()
|
|
: _thread([this]{ this->workerThreadLoop(); } )
|
|
, _newQueries(CreateEvent(NULL, true, true, NULL))
|
|
{
|
|
}
|
|
|
|
RemotePathChecker::~RemotePathChecker()
|
|
{
|
|
_stop = true;
|
|
//_newQueries.notify_all();
|
|
SetEvent(_newQueries);
|
|
_thread.join();
|
|
CloseHandle(_newQueries);
|
|
}
|
|
|
|
vector<wstring> RemotePathChecker::WatchedDirectories()
|
|
{
|
|
std::unique_lock<std::mutex> lock(_mutex);
|
|
return _watchedDirectories;
|
|
}
|
|
|
|
bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, int* state)
|
|
{
|
|
assert(state); assert(filePath);
|
|
|
|
std::unique_lock<std::mutex> lock(_mutex);
|
|
|
|
auto path = std::wstring(filePath);
|
|
|
|
auto it = _cache.find(path);
|
|
if (it != _cache.end()) {
|
|
*state = it->second;
|
|
return true;
|
|
}
|
|
|
|
_pending.push(filePath);
|
|
SetEvent(_newQueries);
|
|
return false;
|
|
|
|
}
|
|
|
|
RemotePathChecker::FileState RemotePathChecker::_StrToFileState(const std::wstring &str)
|
|
{
|
|
if (str == L"NOP" || str == L"NONE") {
|
|
return StateNone;
|
|
} else if (str == L"SYNC" || str == L"NEW") {
|
|
return StateSync;
|
|
} else if (str == L"SYNC+SWM" || str == L"NEW+SWM") {
|
|
return StateSyncSWM;
|
|
} else if (str == L"OK") {
|
|
return StateOk;
|
|
} else if (str == L"OK+SWM") {
|
|
return StateOkSWM;
|
|
} else if (str == L"IGNORE") {
|
|
return StateWarning;
|
|
} else if (str == L"IGNORE+SWM") {
|
|
return StateWarningSWM;
|
|
} else if (str == L"ERROR") {
|
|
return StateError;
|
|
} else if (str == L"ERROR+SWM") {
|
|
return StateErrorSWM;
|
|
}
|
|
|
|
return StateNone;
|
|
} |