Support for multiple icons

This commit is contained in:
Daniel Molkentin 2014-08-04 15:40:08 +02:00
parent 8d71328192
commit 9a1781f613
12 changed files with 183 additions and 135 deletions

View file

@ -37,38 +37,57 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
return TRUE;
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
HRESULT CreateFactory(REFIID riid, void **ppv, int state)
{
HRESULT hResult = CLASS_E_CLASSNOTAVAILABLE;
GUID guid;
hResult = CLSIDFromString(OVERLAY_GUID, (LPCLSID)&guid);
HRESULT hResult = E_OUTOFMEMORY;
if (hResult != S_OK) {
return hResult;
}
if (!IsEqualCLSID(guid, rclsid)) {
return hResult;
}
hResult = E_OUTOFMEMORY;
wchar_t szModule[MAX_PATH];
if (GetModuleFileName(instanceHandle, szModule, ARRAYSIZE(szModule)) == 0) {
hResult = HRESULT_FROM_WIN32(GetLastError());
return hResult;
}
OCOverlayFactory* ocOverlayFactory = new OCOverlayFactory(szModule);
OCOverlayFactory* ocOverlayFactory = new OCOverlayFactory(state);
if (ocOverlayFactory) {
hResult = ocOverlayFactory->QueryInterface(riid, ppv);
ocOverlayFactory->Release();
}
return hResult;
return hResult;
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
HRESULT hResult = CLASS_E_CLASSNOTAVAILABLE;
GUID guid;
hResult = CLSIDFromString(OVERLAY_GUID_ERROR, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_Error); }
hResult = CLSIDFromString(OVERLAY_GUID_ERROR_SHARED, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_ErrorShared); }
hResult = CLSIDFromString(OVERLAY_GUID_OK, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_OK); }
hResult = CLSIDFromString(OVERLAY_GUID_OK_SHARED, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_OKShared); }
hResult = CLSIDFromString(OVERLAY_GUID_SYNC, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_Sync); }
hResult = CLSIDFromString(OVERLAY_GUID_SYNC_SHARED, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_SyncShared); }
hResult = CLSIDFromString(OVERLAY_GUID_WARNING, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_Warning); }
hResult = CLSIDFromString(OVERLAY_GUID_WARNING_SHARED, (LPCLSID)&guid);
if (!SUCCEEDED(hResult)) { return hResult; }
if (IsEqualCLSID(guid, rclsid)) { return CreateFactory(riid, ppv, State_WarningShared); }
return CLASS_E_CLASSNOTAVAILABLE;
}
STDAPI DllCanUnloadNow(void)
@ -78,45 +97,81 @@ STDAPI DllCanUnloadNow(void)
return S_FALSE;
}
HRESULT RegisterCLSID(LPCOLESTR guidStr, PCWSTR overlayStr, PCWSTR szModule)
{
HRESULT hResult = S_OK;
GUID guid;
hResult = CLSIDFromString(guidStr, (LPCLSID)&guid);
if (hResult != S_OK) {
return hResult;
}
hResult = OCOverlayRegistrationHandler::RegisterCOMObject(szModule, guid);
if (!SUCCEEDED(hResult)) {
return hResult;
}
hResult = OCOverlayRegistrationHandler::MakeRegistryEntries(guid, overlayStr);
return hResult;
}
HRESULT _stdcall DllRegisterServer(void)
{
HRESULT hResult = S_OK;
wchar_t szModule[MAX_PATH];
if (GetModuleFileName(instanceHandle, szModule, ARRAYSIZE(szModule)) == 0)
{
if (GetModuleFileName(instanceHandle, szModule, ARRAYSIZE(szModule)) == 0) {
hResult = HRESULT_FROM_WIN32(GetLastError());
return hResult;
}
GUID guid;
hResult = CLSIDFromString(OVERLAY_GUID, (LPCLSID)&guid);
if (hResult != S_OK)
{
return hResult;
}
hResult = OCOverlayRegistrationHandler::RegisterCOMObject(szModule, guid);
if(!SUCCEEDED(hResult))
{
return hResult;
}
hResult = OCOverlayRegistrationHandler::MakeRegistryEntries(guid, OVERLAY_NAME);
if(!SUCCEEDED(hResult))
{
return hResult;
}
hResult = RegisterCLSID(OVERLAY_GUID_ERROR, OVERLAY_NAME_ERROR, szModule);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = RegisterCLSID(OVERLAY_GUID_ERROR_SHARED, OVERLAY_NAME_ERROR_SHARED, szModule);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = RegisterCLSID(OVERLAY_GUID_OK, OVERLAY_NAME_OK, szModule);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = RegisterCLSID(OVERLAY_GUID_OK_SHARED, OVERLAY_NAME_OK_SHARED, szModule);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = RegisterCLSID(OVERLAY_GUID_SYNC, OVERLAY_NAME_SYNC, szModule);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = RegisterCLSID(OVERLAY_GUID_SYNC_SHARED, OVERLAY_NAME_SYNC_SHARED,szModule);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = RegisterCLSID(OVERLAY_GUID_WARNING, OVERLAY_NAME_WARNING, szModule);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = RegisterCLSID(OVERLAY_GUID_WARNING_SHARED, OVERLAY_NAME_WARNING_SHARED, szModule);
return hResult;
}
HRESULT UnregisterCLSID(LPCOLESTR guidStr, PCWSTR overlayStr)
{
HRESULT hResult = S_OK;
GUID guid;
hResult = CLSIDFromString(guidStr, (LPCLSID)&guid);
if (hResult != S_OK) {
return hResult;
}
hResult = OCOverlayRegistrationHandler::UnregisterCOMObject(guid);
if (!SUCCEEDED(hResult)) {
return hResult;
}
hResult = OCOverlayRegistrationHandler::RemoveRegistryEntries(overlayStr);
return hResult;
}
STDAPI DllUnregisterServer(void)
{
HRESULT hResult = S_OK;
@ -128,29 +183,22 @@ STDAPI DllUnregisterServer(void)
hResult = HRESULT_FROM_WIN32(GetLastError());
return hResult;
}
GUID guid;
hResult = CLSIDFromString(OVERLAY_GUID, (LPCLSID)&guid);
if (hResult != S_OK)
{
return hResult;
}
hResult = OCOverlayRegistrationHandler::UnregisterCOMObject(guid);
if(!SUCCEEDED(hResult))
{
return hResult;
}
hResult = OCOverlayRegistrationHandler::RemoveRegistryEntries(OVERLAY_NAME);
if (!SUCCEEDED(hResult))
{
return hResult;
}
hResult = UnregisterCLSID(OVERLAY_GUID_ERROR, OVERLAY_NAME_ERROR);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = UnregisterCLSID(OVERLAY_GUID_ERROR_SHARED, OVERLAY_NAME_ERROR_SHARED);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = UnregisterCLSID(OVERLAY_GUID_OK, OVERLAY_NAME_OK);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = UnregisterCLSID(OVERLAY_GUID_OK_SHARED, OVERLAY_NAME_OK_SHARED);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = UnregisterCLSID(OVERLAY_GUID_SYNC, OVERLAY_NAME_SYNC);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = UnregisterCLSID(OVERLAY_GUID_SYNC_SHARED, OVERLAY_NAME_SYNC_SHARED);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = UnregisterCLSID(OVERLAY_GUID_WARNING, OVERLAY_NAME_WARNING);
if (!SUCCEEDED(hResult)) { return hResult; }
hResult = UnregisterCLSID(OVERLAY_GUID_WARNING_SHARED, OVERLAY_NAME_WARNING_SHARED);
return hResult;
}

View file

@ -33,10 +33,11 @@ extern HINSTANCE instanceHandle;
#define IDM_DISPLAY 0
#define IDB_OK 101
OCOverlay::OCOverlay()
OCOverlay::OCOverlay(int state)
: _communicationSocket(0)
, _referenceCount(1)
, _checker(new RemotePathChecker(PORT))
, _state(state)
{
}
@ -98,20 +99,18 @@ IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority)
// return MAKE_HRESULT(S_FALSE, 0, 0);
//}
bool isDir = dwAttrib & FILE_ATTRIBUTE_DIRECTORY;
if (!_checker->IsMonitoredPath(pwszPath, isDir)) {
int state = 0;
if (!_checker->IsMonitoredPath(pwszPath, &state)) {
return MAKE_HRESULT(S_FALSE, 0, 0);
}
return MAKE_HRESULT(S_OK, 0, 0);
return MAKE_HRESULT(state == _state ? S_OK : S_FALSE, 0, 0);
}
IFACEMETHODIMP OCOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags)
{
*pIndex = 0;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
*pIndex = 2;
*pIndex = _state;
if (GetModuleFileName(instanceHandle, pwszIconFile, cchMax) == 0) {
HRESULT hResult = HRESULT_FROM_WIN32(GetLastError());

View file

@ -25,7 +25,7 @@ class OCOverlay : public IShellIconOverlayIdentifier
{
public:
OCOverlay();
OCOverlay(int state);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags);
@ -44,6 +44,7 @@ private:
long _referenceCount;
CommunicationSocket* _communicationSocket;
RemotePathChecker* _checker;
int _state;
};
#endif

View file

@ -17,8 +17,8 @@
extern long dllReferenceCount;
OCOverlayFactory::OCOverlayFactory(wchar_t* path)
: _referenceCount(1)
OCOverlayFactory::OCOverlayFactory(int state)
: _referenceCount(1), _state(state)
{
InterlockedIncrement(&dllReferenceCount);
}
@ -68,23 +68,13 @@ IFACEMETHODIMP OCOverlayFactory::CreateInstance(
{
HRESULT hResult = CLASS_E_NOAGGREGATION;
if (pUnkOuter != NULL)
{
return hResult;
}
if (pUnkOuter != NULL) { return hResult; }
hResult = E_OUTOFMEMORY;
OCOverlay *lrOverlay =
new (std::nothrow) OCOverlay();
if (!lrOverlay)
{
return hResult;
}
OCOverlay *lrOverlay = new (std::nothrow) OCOverlay(_state);
if (!lrOverlay) { return hResult; }
hResult = lrOverlay->QueryInterface(riid, ppv);
lrOverlay->Release();
return hResult;
@ -92,12 +82,9 @@ IFACEMETHODIMP OCOverlayFactory::CreateInstance(
IFACEMETHODIMP OCOverlayFactory::LockServer(BOOL fLock)
{
if (fLock)
{
if (fLock) {
InterlockedIncrement(&dllReferenceCount);
}
else
{
} else {
InterlockedDecrement(&dllReferenceCount);
}
return S_OK;

View file

@ -19,10 +19,17 @@
#include "stdafx.h"
enum State {
State_Error = 0, State_ErrorShared,
State_OK, State_OKShared,
State_Sync, State_SyncShared,
State_Warning, State_WarningShared
};
class OCOverlayFactory : public IClassFactory
{
public:
OCOverlayFactory(wchar_t* path);
OCOverlayFactory(int state);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv);
@ -35,7 +42,7 @@ protected:
private:
long _referenceCount;
wchar_t* _path;
int _state;
};
#endif

View file

@ -20,7 +20,7 @@
using namespace std;
HRESULT OCOverlayRegistrationHandler::MakeRegistryEntries(const CLSID& clsid, PWSTR friendlyName)
HRESULT OCOverlayRegistrationHandler::MakeRegistryEntries(const CLSID& clsid, PCWSTR friendlyName)
{
HRESULT hResult;
HKEY shellOverlayKey = NULL;
@ -50,7 +50,7 @@ HRESULT OCOverlayRegistrationHandler::MakeRegistryEntries(const CLSID& clsid, PW
return hResult;
}
HRESULT OCOverlayRegistrationHandler::RemoveRegistryEntries(PWSTR friendlyName)
HRESULT OCOverlayRegistrationHandler::RemoveRegistryEntries(PCWSTR friendlyName)
{
HRESULT hResult;
HKEY shellOverlayKey = NULL;

View file

@ -22,9 +22,9 @@
class __declspec(dllexport) OCOverlayRegistrationHandler
{
public:
static HRESULT MakeRegistryEntries(const CLSID& clsid, PWSTR fileType);
static HRESULT MakeRegistryEntries(const CLSID& clsid, PCWSTR fileType);
static HRESULT RegisterCOMObject(PCWSTR modulePath, const CLSID& clsid);
static HRESULT RemoveRegistryEntries(PWSTR friendlyName);
static HRESULT RemoveRegistryEntries(PCWSTR friendlyName);
static HRESULT UnregisterCOMObject(const CLSID& clsid);
};

View file

@ -12,9 +12,24 @@
* details.
*/
#define OVERLAY_ID 1
#define OVERLAY_GUID L"{0960F09E-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_NAME L"OwnCloudStatusOverlay"
#define OVERLAY_GUID_ERROR L"{0960F090-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_GUID_ERROR_SHARED L"{0960F091-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_GUID_OK L"{0960F092-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_GUID_OK_SHARED L"{0960F093-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_GUID_SYNC L"{0960F094-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_GUID_SYNC_SHARED L"{0960F095-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_GUID_WARNING L"{0960F096-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_GUID_WARNING_SHARED L"{0960F097-F328-48A3-B746-276B1E3C3722}"
#define OVERLAY_NAME_ERROR L"OCError"
#define OVERLAY_NAME_ERROR_SHARED L"OCErrorShared"
#define OVERLAY_NAME_OK L"OCOK"
#define OVERLAY_NAME_OK_SHARED L"OCOKShared"
#define OVERLAY_NAME_SYNC L"OCSync"
#define OVERLAY_NAME_SYNC_SHARED L"OCSyncShared"
#define OVERLAY_NAME_WARNING L"OCWarning"
#define OVERLAY_NAME_WARNING_SHARED L"OCWarningShared"
#define REGISTRY_OVERLAY_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers"
#define REGISTRY_CLSID L"CLSID"

View file

@ -3,14 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30501.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OCUtil", "OCUtil\OCUtil.vcxproj", "{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OCOverlays", "OCOverlays\OCOverlays.vcxproj", "{42EFEC79-5ACA-4F76-955F-15CE4340F6BC}"
ProjectSection(ProjectDependencies) = postProject
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3} = {E4F63E19-808D-4234-8DF0-69C5F47C9CD3}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OCUtilTest", "ConsoleApplication1\ConsoleApplication1.vcxproj", "{A81E3DAE-8FE7-4BD0-82F9-939B2D59D033}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OCUtil", "OCUtil\OCUtil.vcxproj", "{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -20,14 +18,6 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|Win32.ActiveCfg = Debug|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|Win32.Build.0 = Debug|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|x64.ActiveCfg = Debug|x64
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|x64.Build.0 = Debug|x64
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|Win32.ActiveCfg = Release|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|Win32.Build.0 = Release|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|x64.ActiveCfg = Release|x64
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|x64.Build.0 = Release|x64
{42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Debug|Win32.ActiveCfg = Debug|Win32
{42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Debug|Win32.Build.0 = Debug|Win32
{42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Debug|x64.ActiveCfg = Debug|x64
@ -36,12 +26,14 @@ Global
{42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Release|Win32.Build.0 = Release|Win32
{42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Release|x64.ActiveCfg = Release|x64
{42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Release|x64.Build.0 = Release|x64
{A81E3DAE-8FE7-4BD0-82F9-939B2D59D033}.Debug|Win32.ActiveCfg = Debug|Win32
{A81E3DAE-8FE7-4BD0-82F9-939B2D59D033}.Debug|Win32.Build.0 = Debug|Win32
{A81E3DAE-8FE7-4BD0-82F9-939B2D59D033}.Debug|x64.ActiveCfg = Debug|Win32
{A81E3DAE-8FE7-4BD0-82F9-939B2D59D033}.Release|Win32.ActiveCfg = Release|Win32
{A81E3DAE-8FE7-4BD0-82F9-939B2D59D033}.Release|Win32.Build.0 = Release|Win32
{A81E3DAE-8FE7-4BD0-82F9-939B2D59D033}.Release|x64.ActiveCfg = Release|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|Win32.ActiveCfg = Debug|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|Win32.Build.0 = Debug|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|x64.ActiveCfg = Debug|x64
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Debug|x64.Build.0 = Debug|x64
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|Win32.ActiveCfg = Release|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|Win32.Build.0 = Release|Win32
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|x64.ActiveCfg = Release|x64
{E4F63E19-808D-4234-8DF0-69C5F47C9CD3}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -37,7 +37,7 @@ RemotePathChecker::RemotePathChecker(int port)
{
}
bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, bool isDir)
bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, int* state)
{
wstring request;
wstring response;
@ -45,11 +45,7 @@ bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, bool isDir)
CommunicationSocket socket(_port);
socket.Connect();
if (isDir) {
request = L"RETRIEVE_FOLDER_STATUS:";
} else {
request = L"RETRIEVE_FILE_STATUS:";
}
request = L"RETRIEVE_FILE_STATUS:";
request += filePath;
request += L'\n';
@ -76,8 +72,11 @@ bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, bool isDir)
wstring responseStatus = response.substr(statusBegin+1, statusEnd - statusBegin-1);
wstring responsePath = response.substr(statusEnd+1);
if (responsePath == filePath) {
int status = _StrToFileState(responseStatus);
if (status == StateNone) {
if (!state) {
return false;
}
*state = _StrToFileState(responseStatus);
if (*state == StateNone) {
return false;
}
needed = true;

View file

@ -29,7 +29,7 @@ public:
StateNone
};
RemotePathChecker(int port);
bool IsMonitoredPath(const wchar_t* filePath, bool isDir);
bool IsMonitoredPath(const wchar_t* filePath, int* state);
private:
int _StrToFileState(const std::wstring &str);