NCOverlay.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /**
  2. * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it under
  5. * the terms of the GNU Lesser General Public License as published by the Free
  6. * Software Foundation; either version 2.1 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  12. * details.
  13. */
  14. #include "NCOverlay.h"
  15. #include "NCOverlayFactory.h"
  16. #include "StringUtil.h"
  17. #include "RemotePathChecker.h"
  18. #include <algorithm>
  19. #include <iostream>
  20. #include <fstream>
  21. #include <memory>
  22. using namespace std;
  23. #pragma comment(lib, "shlwapi.lib")
  24. extern HINSTANCE instanceHandle;
  25. #define IDM_DISPLAY 0
  26. #define IDB_OK 101
  27. namespace {
  28. unique_ptr<RemotePathChecker> s_instance;
  29. RemotePathChecker *getGlobalChecker()
  30. {
  31. // On Vista we'll run into issue #2680 if we try to create the thread+pipe connection
  32. // on any DllGetClassObject of our registered classes.
  33. // Work around the issue by creating the static RemotePathChecker only once actually needed.
  34. static once_flag s_onceFlag;
  35. call_once(s_onceFlag, [] { s_instance.reset(new RemotePathChecker); });
  36. return s_instance.get();
  37. }
  38. }
  39. NCOverlay::NCOverlay(int state)
  40. : _referenceCount(1)
  41. , _state(state)
  42. {
  43. }
  44. NCOverlay::~NCOverlay(void)
  45. {
  46. }
  47. IFACEMETHODIMP_(ULONG) NCOverlay::AddRef()
  48. {
  49. return InterlockedIncrement(&_referenceCount);
  50. }
  51. IFACEMETHODIMP NCOverlay::QueryInterface(REFIID riid, void **ppv)
  52. {
  53. HRESULT hr = S_OK;
  54. if (IsEqualIID(IID_IUnknown, riid) || IsEqualIID(IID_IShellIconOverlayIdentifier, riid))
  55. {
  56. *ppv = static_cast<IShellIconOverlayIdentifier *>(this);
  57. }
  58. else
  59. {
  60. hr = E_NOINTERFACE;
  61. *ppv = nullptr;
  62. }
  63. if (*ppv)
  64. {
  65. AddRef();
  66. }
  67. return hr;
  68. }
  69. IFACEMETHODIMP_(ULONG) NCOverlay::Release()
  70. {
  71. ULONG cRef = InterlockedDecrement(&_referenceCount);
  72. if (0 == cRef)
  73. {
  74. delete this;
  75. }
  76. return cRef;
  77. }
  78. IFACEMETHODIMP NCOverlay::GetPriority(int *pPriority)
  79. {
  80. // this defines which handler has prededence, so
  81. // we order this in terms of likelyhood
  82. switch (_state) {
  83. case State_OK:
  84. *pPriority = 0; break;
  85. case State_OKShared:
  86. *pPriority = 1; break;
  87. case State_Warning:
  88. *pPriority = 2; break;
  89. case State_Sync:
  90. *pPriority = 3; break;
  91. case State_Error:
  92. *pPriority = 4; break;
  93. default:
  94. *pPriority = 5; break;
  95. }
  96. return S_OK;
  97. }
  98. IFACEMETHODIMP NCOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib)
  99. {
  100. RemotePathChecker* checker = getGlobalChecker();
  101. std::shared_ptr<const std::vector<std::wstring>> watchedDirectories = checker->WatchedDirectories();
  102. if (watchedDirectories->empty()) {
  103. return MAKE_HRESULT(S_FALSE, 0, 0);
  104. }
  105. bool watched = false;
  106. size_t pathLength = wcslen(pwszPath);
  107. for (auto it = watchedDirectories->begin(); it != watchedDirectories->end(); ++it) {
  108. if (StringUtil::isDescendantOf(pwszPath, pathLength, *it)) {
  109. watched = true;
  110. }
  111. }
  112. if (!watched) {
  113. return MAKE_HRESULT(S_FALSE, 0, 0);
  114. }
  115. int state = 0;
  116. if (!checker->IsMonitoredPath(pwszPath, &state)) {
  117. return MAKE_HRESULT(S_FALSE, 0, 0);
  118. }
  119. return MAKE_HRESULT(state == _state ? S_OK : S_FALSE, 0, 0);
  120. }
  121. IFACEMETHODIMP NCOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags)
  122. {
  123. *pIndex = 0;
  124. *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
  125. *pIndex = _state;
  126. if (GetModuleFileName(instanceHandle, pwszIconFile, cchMax) == 0) {
  127. HRESULT hResult = HRESULT_FROM_WIN32(GetLastError());
  128. wcerr << L"IsOK? " << (hResult == S_OK) << L" with path " << pwszIconFile << L", index " << *pIndex << endl;
  129. return hResult;
  130. }
  131. return S_OK;
  132. }