nextcloud-desktop/shell_integration/windows/OCOverlays/OCOverlay.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

171 lines
4.1 KiB
C++
Raw Normal View History

2014-07-30 19:20:55 +04:00
/**
* Copyright (c) 2000-2013 Liferay, 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; either version 2.1 of the License, or (at your option)
* any later version.
*
* 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 "stdafx.h"
2014-07-30 19:20:55 +04:00
#include "OCOverlay.h"
#include "OCOverlayFactory.h"
2014-07-30 19:20:55 +04:00
#include "RegistryUtil.h"
#include "StringUtil.h"
2014-07-30 19:20:55 +04:00
#include "UtilConstants.h"
#include "RemotePathChecker.h"
#include "resource.h"
#include <algorithm>
#include <iostream>
#include <fstream>
#include <memory>
2014-07-30 19:20:55 +04:00
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();
}
}
2014-08-04 17:40:08 +04:00
OCOverlay::OCOverlay(int state)
: _referenceCount(1)
, _state(state)
2014-07-30 19:20:55 +04:00
{
}
OCOverlay::~OCOverlay(void)
{
}
2014-07-30 19:20:55 +04:00
IFACEMETHODIMP_(ULONG) OCOverlay::AddRef()
{
return InterlockedIncrement(&_referenceCount);
}
IFACEMETHODIMP OCOverlay::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 = NULL;
}
if (*ppv)
{
AddRef();
}
2014-07-30 19:20:55 +04:00
return hr;
}
IFACEMETHODIMP_(ULONG) OCOverlay::Release()
{
ULONG cRef = InterlockedDecrement(&_referenceCount);
if (0 == cRef)
{
delete this;
}
return cRef;
}
IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority)
{
// this defines which handler has prededence, so
// we order this in terms of likelyhood
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;
2014-07-30 19:20:55 +04:00
}
IFACEMETHODIMP OCOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib)
2014-07-30 19:20:55 +04:00
{
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);
2014-07-30 19:20:55 +04:00
}
IFACEMETHODIMP OCOverlay::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;
}
2014-07-30 19:20:55 +04:00
return S_OK;
2014-07-30 19:20:55 +04:00
}