1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
/*
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2014 ownCloud GmbH
* SPDX-FileCopyrightText: 2000-2013 Liferay, Inc. All rights reserved
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "NCOverlay.h"
#include "NCOverlayFactory.h"
#include "StringUtil.h"
#include "RemotePathChecker.h"
#include <algorithm>
#include <iostream>
#include <fstream>
#include <memory>
using namespace std;
#pragma comment(lib, "shlwapi.lib")
extern HINSTANCE instanceHandle;
#define IDM_DISPLAY 0
#define IDB_OK 101
namespace {
unique_ptr<RemotePathChecker> s_instance;
RemotePathChecker *getGlobalChecker()
{
// On Vista we'll run into issue #2680 if we try to create the thread+pipe connection
// on any DllGetClassObject of our registered classes.
// Work around the issue by creating the static RemotePathChecker only once actually needed.
static once_flag s_onceFlag;
call_once(s_onceFlag, [] { s_instance.reset(new RemotePathChecker); });
return s_instance.get();
}
}
NCOverlay::NCOverlay(int state)
: _referenceCount(1)
, _state(state)
{
}
NCOverlay::~NCOverlay(void)
{
}
IFACEMETHODIMP_(ULONG) NCOverlay::AddRef()
{
return InterlockedIncrement(&_referenceCount);
}
IFACEMETHODIMP NCOverlay::QueryInterface(REFIID riid, void **ppv)
{
HRESULT hr = S_OK;
if (IsEqualIID(IID_IUnknown, riid) || IsEqualIID(IID_IShellIconOverlayIdentifier, riid))
{
*ppv = static_cast<IShellIconOverlayIdentifier *>(this);
}
else
{
hr = E_NOINTERFACE;
*ppv = nullptr;
}
if (*ppv)
{
AddRef();
}
return hr;
}
IFACEMETHODIMP_(ULONG) NCOverlay::Release()
{
ULONG cRef = InterlockedDecrement(&_referenceCount);
if (0 == cRef)
{
delete this;
}
return cRef;
}
IFACEMETHODIMP NCOverlay::GetPriority(int *pPriority)
{
// this defines which handler has precedence, so
// we order this in terms of likelihood
switch (_state) {
case State_OK:
*pPriority = 0; break;
case State_OKShared:
*pPriority = 1; break;
case State_Warning:
*pPriority = 2; break;
case State_Sync:
*pPriority = 3; break;
case State_Error:
*pPriority = 4; break;
default:
*pPriority = 5; break;
}
return S_OK;
}
IFACEMETHODIMP NCOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib)
{
RemotePathChecker* checker = getGlobalChecker();
std::shared_ptr<const std::vector<std::wstring>> watchedDirectories = checker->WatchedDirectories();
if (watchedDirectories->empty()) {
return MAKE_HRESULT(S_FALSE, 0, 0);
}
bool watched = false;
size_t pathLength = wcslen(pwszPath);
for (auto it = watchedDirectories->begin(); it != watchedDirectories->end(); ++it) {
if (StringUtil::isDescendantOf(pwszPath, pathLength, *it)) {
watched = true;
}
}
if (!watched) {
return MAKE_HRESULT(S_FALSE, 0, 0);
}
int state = 0;
if (!checker->IsMonitoredPath(pwszPath, &state)) {
return MAKE_HRESULT(S_FALSE, 0, 0);
}
return MAKE_HRESULT(state == _state ? S_OK : S_FALSE, 0, 0);
}
IFACEMETHODIMP NCOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags)
{
*pIndex = 0;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
*pIndex = _state;
if (GetModuleFileName(instanceHandle, pwszIconFile, cchMax) == 0) {
HRESULT hResult = HRESULT_FROM_WIN32(GetLastError());
wcerr << L"IsOK? " << (hResult == S_OK) << L" with path " << pwszIconFile << L", index " << *pIndex << endl;
return hResult;
}
return S_OK;
}
|