From 8d7132819228e6c21b8a190f09ce16d509abdabd Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Wed, 30 Jul 2014 17:20:55 +0200 Subject: [PATCH] Windows Overlay Icons --- .gitignore | 145 +++++++ .../OCShellExtensions/OCOverlays/DllMain.cpp | 156 +++++++ .../OCOverlays/OCOverlay.cpp | 143 +++++++ .../OCShellExtensions/OCOverlays/OCOverlay.h | 49 +++ .../OCShellExtensions/OCOverlays/OCOverlay.rc | Bin 0 -> 4244 bytes .../OCOverlays/OCOverlayFactory.cpp | 104 +++++ .../OCOverlays/OCOverlayFactory.h | 41 ++ .../OCOverlayRegistrationHandler.cpp | 149 +++++++ .../OCOverlays/OCOverlayRegistrationHandler.h | 31 ++ .../OCOverlays/OCOverlays.def | 6 + .../OCOverlays/OCOverlays.vcxproj | 195 +++++++++ .../OCOverlays/OverlayConstants.h | 32 ++ .../OCOverlays/OverlayConstants.h.original | 32 ++ .../OCOverlays/ico/Error.ico | Bin 0 -> 30166 bytes .../OCOverlays/ico/Error_Shared.ico | Bin 0 -> 30166 bytes .../OCShellExtensions/OCOverlays/ico/OK.ico | Bin 0 -> 30166 bytes .../OCOverlays/ico/OK_Shared.ico | Bin 0 -> 30166 bytes .../OCShellExtensions/OCOverlays/ico/Sync.ico | Bin 0 -> 30166 bytes .../OCOverlays/ico/Sync_Shared.ico | Bin 0 -> 30166 bytes .../OCOverlays/ico/Warning.ico | Bin 0 -> 30166 bytes .../OCOverlays/ico/Warning_Shared.ico | Bin 0 -> 30166 bytes .../OCShellExtensions/OCOverlays/resource.h | Bin 0 -> 1626 bytes .../OCShellExtensions/OCOverlays/stdafx.h | 30 ++ .../OCShellExtensions/OCShellExtensions.sln | 49 +++ .../OCUtil/CommunicationSocket.cpp | 127 ++++++ .../OCUtil/CommunicationSocket.h | 42 ++ .../OCShellExtensions/OCUtil/FileUtil.cpp | 84 ++++ .../OCShellExtensions/OCUtil/FileUtil.h | 40 ++ .../OCShellExtensions/OCUtil/OCMessage.cpp | 74 ++++ .../OCShellExtensions/OCUtil/OCMessage.h | 42 ++ .../OCShellExtensions/OCUtil/OCUtil.vcxproj | 157 +++++++ .../OCShellExtensions/OCUtil/ParserUtil.cpp | 389 ++++++++++++++++++ .../OCShellExtensions/OCUtil/RegistryUtil.cpp | 70 ++++ .../OCShellExtensions/OCUtil/RegistryUtil.h | 35 ++ .../OCUtil/RemotePathChecker.cpp | 112 +++++ .../OCUtil/RemotePathChecker.h | 41 ++ .../OCShellExtensions/OCUtil/StringUtil.cpp | 32 ++ .../OCShellExtensions/OCUtil/StringUtil.h | 27 ++ .../OCShellExtensions/OCUtil/UtilConstants.h | 30 ++ .../OCUtilTest/OCUtilTest.cpp | 37 ++ .../OCUtilTest/OCUtilTest.filters | 33 ++ .../OCUtilTest/OCUtilTest.vcxproj | 97 +++++ .../OCShellExtensions/OCUtilTest/ReadMe.txt | 40 ++ .../OCShellExtensions/OCUtilTest/stdafx.cpp | 8 + .../OCShellExtensions/OCUtilTest/stdafx.h | 15 + .../OCShellExtensions/OCUtilTest/targetver.h | 8 + 46 files changed, 2702 insertions(+) create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/DllMain.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.h create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.rc create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.h create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.h create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.def create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.vcxproj create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h.original create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/Error.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/Error_Shared.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/OK.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/OK_Shared.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/Sync.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/Sync_Shared.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/Warning.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/ico/Warning_Shared.ico create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/resource.h create mode 100644 shell_integration/windows/OCShellExtensions/OCOverlays/stdafx.h create mode 100644 shell_integration/windows/OCShellExtensions/OCShellExtensions.sln create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/OCUtil.vcxproj create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/ParserUtil.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtil/UtilConstants.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.filters create mode 100644 shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.vcxproj create mode 100644 shell_integration/windows/OCShellExtensions/OCUtilTest/ReadMe.txt create mode 100644 shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.cpp create mode 100644 shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.h create mode 100644 shell_integration/windows/OCShellExtensions/OCUtilTest/targetver.h diff --git a/.gitignore b/.gitignore index eed2de186..e1cd73027 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,148 @@ build* cscope.* tags t1.cfg + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +## TODO: Comment the next line if you want to checkin your +## web deploy settings but do note that will include unencrypted +## passwords +*.pubxml + +# NuGet Packages +packages/* +*.nupkg +## TODO: If the tool you use requires repositories.config +## uncomment the next line +#!packages/repositories.config + +# Enable "build/" folder in the NuGet Packages folder since +# NuGet packages use it for MSBuild targets. +# This line needs to be after the ignore of the build folder +# (and the packages folder if the line above has been uncommented) +!packages/build/ + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Microsoft Fakes +FakesAssemblies/ diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/DllMain.cpp b/shell_integration/windows/OCShellExtensions/OCOverlays/DllMain.cpp new file mode 100644 index 000000000..84b128dd4 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/DllMain.cpp @@ -0,0 +1,156 @@ +/** + * 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 "OCOverlayRegistrationHandler.h" +#include "OCOverlayFactory.h" +#include "stdafx.h" + +HINSTANCE instanceHandle = NULL; + +long dllReferenceCount = 0; + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + instanceHandle = hModule; + DisableThreadLibraryCalls(hModule); + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) +{ + HRESULT hResult = CLASS_E_CLASSNOTAVAILABLE; + GUID guid; + + hResult = CLSIDFromString(OVERLAY_GUID, (LPCLSID)&guid); + + 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); + + if (ocOverlayFactory) { + hResult = ocOverlayFactory->QueryInterface(riid, ppv); + ocOverlayFactory->Release(); + } + return hResult; +} + +STDAPI DllCanUnloadNow(void) +{ + return dllReferenceCount > 0 ? S_FALSE : S_OK; + + return S_FALSE; +} + +HRESULT _stdcall DllRegisterServer(void) +{ + HRESULT hResult = S_OK; + + wchar_t szModule[MAX_PATH]; + + 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; + } + + return hResult; +} + +STDAPI DllUnregisterServer(void) +{ + HRESULT hResult = S_OK; + + wchar_t szModule[MAX_PATH]; + + if (GetModuleFileNameW(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::UnregisterCOMObject(guid); + + if(!SUCCEEDED(hResult)) + { + return hResult; + } + + hResult = OCOverlayRegistrationHandler::RemoveRegistryEntries(OVERLAY_NAME); + + if (!SUCCEEDED(hResult)) + { + return hResult; + } + + return hResult; +} diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.cpp b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.cpp new file mode 100644 index 000000000..2fc947121 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.cpp @@ -0,0 +1,143 @@ +/** + * 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 "OCOverlay.h" + +#include "RegistryUtil.h" +#include "UtilConstants.h" +#include "RemotePathChecker.h" + +#include "resource.h" + +#include +#include +#include + +using namespace std; + +#pragma comment(lib, "shlwapi.lib") + +extern HINSTANCE instanceHandle; + +#define IDM_DISPLAY 0 +#define IDB_OK 101 + +OCOverlay::OCOverlay() + : _communicationSocket(0) + , _referenceCount(1) + , _checker(new RemotePathChecker(PORT)) + +{ +} + +OCOverlay::~OCOverlay(void) +{ +} + +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(this); + } + else + { + hr = E_NOINTERFACE; + *ppv = NULL; + } + + if (*ppv) + { + AddRef(); + } + + return hr; +} + +IFACEMETHODIMP_(ULONG) OCOverlay::Release() +{ + ULONG cRef = InterlockedDecrement(&_referenceCount); + if (0 == cRef) + { + delete this; + } + + return cRef; +} + +IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority) +{ + pPriority = 0; + + return S_OK; +} + + IFACEMETHODIMP OCOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib) +{ + + //if(!_IsOverlaysEnabled()) + //{ + // return MAKE_HRESULT(S_FALSE, 0, 0); + //} + + bool isDir = dwAttrib & FILE_ATTRIBUTE_DIRECTORY; + + if (!_checker->IsMonitoredPath(pwszPath, isDir)) { + return MAKE_HRESULT(S_FALSE, 0, 0); + } + + return MAKE_HRESULT(S_OK, 0, 0); +} + +IFACEMETHODIMP OCOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags) +{ + *pIndex = 0; + *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX; + *pIndex = 2; + + 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; +} + + +bool OCOverlay::_IsOverlaysEnabled() +{ + //int enable; + bool success = false; + + + + + //if(RegistryUtil::ReadRegistry(REGISTRY_ROOT_KEY, REGISTRY_ENABLE_OVERLAY, &enable)) + //{ + // if(enable) { + // success = true; + // } + //} + + return success; +} + diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.h b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.h new file mode 100644 index 000000000..498800a66 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.h @@ -0,0 +1,49 @@ +/** + * 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. + */ + +#ifndef OCOVERLAY_H +#define OCOVERLAY_H + +#include "stdafx.h" + +#pragma once + +class RemotePathChecker; + +class OCOverlay : public IShellIconOverlayIdentifier + +{ +public: + OCOverlay(); + + IFACEMETHODIMP_(ULONG) AddRef(); + IFACEMETHODIMP GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags); + IFACEMETHODIMP GetPriority(int *pPriority); + IFACEMETHODIMP IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib); + IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv); + IFACEMETHODIMP_(ULONG) Release(); + +protected: + ~OCOverlay(void); + +private: + //bool _GenerateMessage(const wchar_t*, std::wstring*); + + bool _IsOverlaysEnabled(); + long _referenceCount; + CommunicationSocket* _communicationSocket; + RemotePathChecker* _checker; +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.rc b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlay.rc new file mode 100644 index 0000000000000000000000000000000000000000..8d4d30b6d48b50535658f4c44ddc2e3a4a7bc80c GIT binary patch literal 4244 zcmds)+ip@p6o%KeiSIDNjg6-D@C2n)BvNXiEt-&!21J@r+OWZD(q~t{e`b%IHejI_ zXeOJPz4n@!fBsn~e*HYK19Ns_SJt+n-B`lYwGpxlWQmRK()zp|*$bMpulB_TJVWFo z`VO)oz2=P>wHZ6!wAz*3qO)&L?FqXa_&$$xz}G(79j}{Pn7?m5%Xw|h%zM4ApQp7C z?W5K0%+9T7WjnQ&)$AB)k#W^3_8Cc?-xDh!sW6WF3&ZZUh%WZdO7JqzaTk_u?3(kB zU`IThaq3U}mO1qi=M*2u$lvhH-^ltqxa8Kqr}Jj{-#x}6qF^0kxRNDxIrnC^5t)zc z?p7bsIc|4=|Mk6J_Bicx?tH*o^us!%;FXE(WmrKn=q$@EK>l&TNj|V^@t=zY*ab=S|vLb#CJDra=IcpMsnpkv*{S%bS5WU?H(L?vi`*_^J(-dPu zQ;f)pH;dL5?`XH8$}}1w)O+k5meMBM4E{)_&oKGw?9N9Y#iBm?ckq-DgQQX9_nWUB z#y(r!qH*b~162&l=EGEX#7yTIR<)tb<qpBi7Bj8SW z7ZT-B;R&-<$*7h|>___bnm*)4AujvMLGep=uBcO^o$|z6pY&y-qUw!_Wc4VQVsB#M z$DC5xe8}E9;Z17st1+mmX;9Tn_IVr(TDJ#-V!rbih!jaD7-mP?Akw<)`H2W;xg%OC9@Ejl7JcgqF`x`mu>JgynU+HQ3bS~ zmsuRM>^vThRqQO!8IM!NO~>!u8pm7_d*%Nw_x8V5Xxsf;Qw_8F-&*8xw{CeFjSw!k Q_W}7$Ie78ES$3`T8y~~`&j0`b literal 0 HcmV?d00001 diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.cpp b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.cpp new file mode 100644 index 000000000..f2d344c02 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.cpp @@ -0,0 +1,104 @@ +/** + * 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 "OCOverlayFactory.h" +#include "OCOverlay.h" + +extern long dllReferenceCount; + +OCOverlayFactory::OCOverlayFactory(wchar_t* path) + : _referenceCount(1) +{ + InterlockedIncrement(&dllReferenceCount); +} + +OCOverlayFactory::~OCOverlayFactory() +{ + InterlockedDecrement(&dllReferenceCount); +} + +IFACEMETHODIMP OCOverlayFactory::QueryInterface(REFIID riid, void **ppv) +{ + HRESULT hResult = S_OK; + + if (IsEqualIID(IID_IUnknown, riid) || + IsEqualIID(IID_IClassFactory, riid)) + { + *ppv = static_cast(this); + AddRef(); + } + else + { + hResult = E_NOINTERFACE; + *ppv = NULL; + } + + return hResult; +} + +IFACEMETHODIMP_(ULONG) OCOverlayFactory::AddRef() +{ + return InterlockedIncrement(&_referenceCount); +} + +IFACEMETHODIMP_(ULONG) OCOverlayFactory::Release() +{ + ULONG cRef = InterlockedDecrement(&_referenceCount); + + if (0 == cRef) + { + delete this; + } + return cRef; +} + +IFACEMETHODIMP OCOverlayFactory::CreateInstance( + IUnknown *pUnkOuter, REFIID riid, void **ppv) +{ + HRESULT hResult = CLASS_E_NOAGGREGATION; + + if (pUnkOuter != NULL) + { + return hResult; + } + + hResult = E_OUTOFMEMORY; + + OCOverlay *lrOverlay = + new (std::nothrow) OCOverlay(); + + if (!lrOverlay) + { + return hResult; + } + + hResult = lrOverlay->QueryInterface(riid, ppv); + + lrOverlay->Release(); + + return hResult; +} + +IFACEMETHODIMP OCOverlayFactory::LockServer(BOOL fLock) +{ + if (fLock) + { + InterlockedIncrement(&dllReferenceCount); + } + else + { + InterlockedDecrement(&dllReferenceCount); + } + return S_OK; +} \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.h b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.h new file mode 100644 index 000000000..6751e5b57 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayFactory.h @@ -0,0 +1,41 @@ +/** + * 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. + */ + +#ifndef OCOVERLAYFACTORY_H +#define OCOVERLAYFACTORY_H + +#pragma once + +#include "stdafx.h" + +class OCOverlayFactory : public IClassFactory +{ +public: + OCOverlayFactory(wchar_t* path); + + IFACEMETHODIMP_(ULONG) AddRef(); + IFACEMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv); + IFACEMETHODIMP LockServer(BOOL fLock); + IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv); + IFACEMETHODIMP_(ULONG) Release(); + +protected: + ~OCOverlayFactory(); + +private: + long _referenceCount; + wchar_t* _path; +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.cpp b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.cpp new file mode 100644 index 000000000..3fc0729f1 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.cpp @@ -0,0 +1,149 @@ +/** + * 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 "OCOverlayRegistrationHandler.h" +#include "stdafx.h" + +#include +#include + +using namespace std; + +HRESULT OCOverlayRegistrationHandler::MakeRegistryEntries(const CLSID& clsid, PWSTR friendlyName) +{ + HRESULT hResult; + HKEY shellOverlayKey = NULL; + hResult = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_OVERLAY_KEY, 0, KEY_WRITE, &shellOverlayKey)); + if (!SUCCEEDED(hResult)) { + hResult = RegCreateKey(HKEY_LOCAL_MACHINE, REGISTRY_OVERLAY_KEY, &shellOverlayKey); + if(!SUCCEEDED(hResult)) { + return hResult; + } + } + + HKEY syncExOverlayKey = NULL; + hResult = HRESULT_FROM_WIN32(RegCreateKeyEx(shellOverlayKey, friendlyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &syncExOverlayKey, NULL)); + + if (!SUCCEEDED(hResult)) { + return hResult; + } + + wchar_t stringCLSID[MAX_PATH]; + StringFromGUID2(clsid, stringCLSID, ARRAYSIZE(stringCLSID)); + LPCTSTR value = stringCLSID; + hResult = RegSetValueEx(syncExOverlayKey, NULL, 0, REG_SZ, (LPBYTE)value, (DWORD)((wcslen(value)+1) * sizeof(TCHAR))); + if (!SUCCEEDED(hResult)) { + return hResult; + } + + return hResult; +} + +HRESULT OCOverlayRegistrationHandler::RemoveRegistryEntries(PWSTR friendlyName) +{ + HRESULT hResult; + HKEY shellOverlayKey = NULL; + hResult = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_OVERLAY_KEY, 0, KEY_WRITE, &shellOverlayKey)); + + if (!SUCCEEDED(hResult)) { + return hResult; + } + + HKEY syncExOverlayKey = NULL; + hResult = HRESULT_FROM_WIN32(RegDeleteKeyEx(shellOverlayKey, friendlyName, DELETE, 0)); + if (!SUCCEEDED(hResult)) { + return hResult; + } + + return hResult; +} + +HRESULT OCOverlayRegistrationHandler::RegisterCOMObject(PCWSTR modulePath, const CLSID& clsid) +{ + if (modulePath == NULL) { + return E_FAIL; + } + + wchar_t stringCLSID[MAX_PATH]; + StringFromGUID2(clsid, stringCLSID, ARRAYSIZE(stringCLSID)); + HRESULT hResult; + HKEY hKey = NULL; + + hResult = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CLASSES_ROOT, REGISTRY_CLSID, 0, KEY_WRITE, &hKey)); + if (!SUCCEEDED(hResult)) { + return hResult; + } + + HKEY clsidKey = NULL; + hResult = HRESULT_FROM_WIN32(RegCreateKeyEx(hKey, stringCLSID, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &clsidKey, NULL)); + if(!SUCCEEDED(hResult)) { + return hResult; + } + + HKEY inprocessKey = NULL; + hResult = HRESULT_FROM_WIN32(RegCreateKeyEx(clsidKey, REGISTRY_IN_PROCESS, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &inprocessKey, NULL)); + if(!SUCCEEDED(hResult)) { + return hResult; + } + + DWORD cbData = lstrlen(modulePath) * sizeof(*modulePath); + hResult = HRESULT_FROM_WIN32(RegSetValue(inprocessKey, NULL, REG_SZ, modulePath, cbData)); + + if(!SUCCEEDED(hResult)) { + return hResult; + } + + hResult = HRESULT_FROM_WIN32(RegSetValueEx(inprocessKey, REGISTRY_THREADING, 0, REG_SZ, (LPBYTE)REGISTRY_APARTMENT, (DWORD)((wcslen(REGISTRY_APARTMENT)+1) * sizeof(TCHAR)))); + if(!SUCCEEDED(hResult)) { + return hResult; + } + + hResult = HRESULT_FROM_WIN32(RegSetValueEx(inprocessKey, REGISTRY_VERSION, 0, REG_SZ, (LPBYTE)REGISTRY_VERSION_NUMBER, (DWORD)(wcslen(REGISTRY_VERSION_NUMBER)+1) * sizeof(TCHAR))); + if(!SUCCEEDED(hResult)) { + return hResult; + } + + return S_OK; +} + +HRESULT OCOverlayRegistrationHandler::UnregisterCOMObject(const CLSID& clsid) +{ + wchar_t stringCLSID[MAX_PATH]; + + StringFromGUID2(clsid, stringCLSID, ARRAYSIZE(stringCLSID)); + HRESULT hResult; + HKEY hKey = NULL; + hResult = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CLASSES_ROOT, REGISTRY_CLSID, 0, DELETE, &hKey)); + if (!SUCCEEDED(hResult)) { + return hResult; + } + + HKEY clsidKey = NULL; + hResult = HRESULT_FROM_WIN32(RegOpenKeyEx(hKey, stringCLSID, 0, DELETE, &clsidKey)); + if(!SUCCEEDED(hResult)) { + return hResult; + } + + hResult = HRESULT_FROM_WIN32(RegDeleteKeyEx(clsidKey, REGISTRY_IN_PROCESS, DELETE, 0)); + if(!SUCCEEDED(hResult)) { + return hResult; + } + + hResult = HRESULT_FROM_WIN32(RegDeleteKeyEx(hKey, stringCLSID, DELETE, 0)); + if(!SUCCEEDED(hResult)) { + return hResult; + } + + return S_OK; +} \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.h b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.h new file mode 100644 index 000000000..1fdef93a7 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlayRegistrationHandler.h @@ -0,0 +1,31 @@ +/** + * 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. + */ + +#ifndef OCOVERLAYREGISTRATIONHANDLER_H +#define OCOVERLAYREGISTRATIONHANDLER_H + +#pragma once + +#include "stdafx.h" + +class __declspec(dllexport) OCOverlayRegistrationHandler +{ + public: + static HRESULT MakeRegistryEntries(const CLSID& clsid, PWSTR fileType); + static HRESULT RegisterCOMObject(PCWSTR modulePath, const CLSID& clsid); + static HRESULT RemoveRegistryEntries(PWSTR friendlyName); + static HRESULT UnregisterCOMObject(const CLSID& clsid); +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.def b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.def new file mode 100644 index 000000000..8cde2bd02 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.def @@ -0,0 +1,6 @@ +LIBRARY +EXPORTS + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.vcxproj b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.vcxproj new file mode 100644 index 000000000..b9f352b22 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OCOverlays.vcxproj @@ -0,0 +1,195 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {42EFEC79-5ACA-4F76-955F-15CE4340F6BC} + OCOverlays + + + + DynamicLibrary + true + Unicode + v120_xp + + + DynamicLibrary + true + Unicode + v120_xp + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + $(ProjectName)_x86 + .dll + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + $(ProjectName)_x64 + .dll + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + $(ProjectName)_x86 + .dll + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + $(ProjectName)_x64 + .dll + + + + Level3 + Disabled + ..\OCUtil;%(AdditionalIncludeDirectories) + false + + + true + ..\$(Configuration)\$(Platform); + OCUtil_x86.lib;%(AdditionalDependencies) + OCOverlays.def + + + + + Level3 + Disabled + ..\OCUtil;%(AdditionalIncludeDirectories) + false + + + true + ..\$(Configuration)\$(Platform); + OCUtil_x64.lib;%(AdditionalDependencies) + OCOverlays.def + + + + + Level3 + MaxSpeed + true + true + ..\OCUtil;%(AdditionalIncludeDirectories) + + + true + true + true + ..\$(Configuration)\$(Platform); + OCUtil_x86.lib;%(AdditionalDependencies) + OCOverlays.def + + + + + Level3 + MaxSpeed + true + true + ..\OCUtil;%(AdditionalIncludeDirectories) + + + true + true + true + ..\$(Configuration)\$(Platform); + OCUtil_x64.lib;%(AdditionalDependencies) + OCOverlays.def + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h b/shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h new file mode 100644 index 000000000..9df0bc5d0 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h @@ -0,0 +1,32 @@ +/** +* 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. +*/ + +#define OVERLAY_ID 1 +#define OVERLAY_GUID L"{0960F09E-F328-48A3-B746-276B1E3C3722}" +#define OVERLAY_NAME L"OwnCloudStatusOverlay" + +#define REGISTRY_OVERLAY_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers" +#define REGISTRY_CLSID L"CLSID" +#define REGISTRY_IN_PROCESS L"InprocServer32" +#define REGISTRY_THREADING L"ThreadingModel" +#define REGISTRY_APARTMENT L"Apartment" +#define REGISTRY_VERSION L"Version" +#define REGISTRY_VERSION_NUMBER L"1.0" + +//Registry values for running +#define REGISTRY_ENABLE_OVERLAY L"EnableOverlay" + +#define GET_FILE_OVERLAY_ID L"getFileIconId" + +#define PORT 33001 \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h.original b/shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h.original new file mode 100644 index 000000000..e244e1515 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/OverlayConstants.h.original @@ -0,0 +1,32 @@ +/** + * 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. + */ + +#define OVERLAY_ID [$overlay.id$] +#define OVERLAY_GUID L"[$overlay.guid$]" +#define OVERLAY_NAME L"[$overlay.name$]" + +#define REGISTRY_OVERLAY_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers" +#define REGISTRY_CLSID L"CLSID" +#define REGISTRY_IN_PROCESS L"InprocServer32" +#define REGISTRY_THREADING L"ThreadingModel" +#define REGISTRY_APARTMENT L"Apartment" +#define REGISTRY_VERSION L"Version" +#define REGISTRY_VERSION_NUMBER L"1.0" + +//Registry values for running +#define REGISTRY_ENABLE_OVERLAY L"EnableOverlay" + +#define GET_FILE_OVERLAY_ID L"getFileIconId" + +#define PORT 33001 diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Error.ico b/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Error.ico new file mode 100644 index 0000000000000000000000000000000000000000..ebcaa7f98c4140b1afc71401e113e668e6cc7113 GIT binary patch literal 30166 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 literal 0 HcmV?d00001 diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Error_Shared.ico b/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Error_Shared.ico new file mode 100644 index 0000000000000000000000000000000000000000..02c963937b94281313b1e6d85db9ac0b0031f7ac GIT binary patch literal 30166 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 G?fO5uP7?6| literal 0 HcmV?d00001 diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/ico/OK.ico b/shell_integration/windows/OCShellExtensions/OCOverlays/ico/OK.ico new file mode 100644 index 0000000000000000000000000000000000000000..f285d9c757c45178a4bfa50025351366e0dc0580 GIT binary patch literal 30166 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 UU9cQZ(H8H&Ph6JVur}=ZKipkf4FCWD literal 0 HcmV?d00001 diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Warning.ico b/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Warning.ico new file mode 100644 index 0000000000000000000000000000000000000000..b7fabc3bf67125141cd7705f139368abc88ea773 GIT binary patch literal 30166 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 literal 0 HcmV?d00001 diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Warning_Shared.ico b/shell_integration/windows/OCShellExtensions/OCOverlays/ico/Warning_Shared.ico new file mode 100644 index 0000000000000000000000000000000000000000..fc85d46d0acc51d848b5101e85a9a99afae16556 GIT binary patch literal 30166 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 literal 0 HcmV?d00001 diff --git a/shell_integration/windows/OCShellExtensions/OCOverlays/stdafx.h b/shell_integration/windows/OCShellExtensions/OCOverlays/stdafx.h new file mode 100644 index 000000000..81121202b --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCOverlays/stdafx.h @@ -0,0 +1,30 @@ +/** + * 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. + */ + +#define WIN32_LEAN_AND_MEAN + +#include "CommunicationSocket.h" +#include "RegistryUtil.h" +#include "OverlayConstants.h" +#include "FileUtil.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/shell_integration/windows/OCShellExtensions/OCShellExtensions.sln b/shell_integration/windows/OCShellExtensions/OCShellExtensions.sln new file mode 100644 index 000000000..979c155fa --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCShellExtensions.sln @@ -0,0 +1,49 @@ + +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}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + 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 + {42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Debug|x64.Build.0 = Debug|x64 + {42EFEC79-5ACA-4F76-955F-15CE4340F6BC}.Release|Win32.ActiveCfg = Release|Win32 + {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 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.cpp b/shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.cpp new file mode 100644 index 000000000..92f404848 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.cpp @@ -0,0 +1,127 @@ +/** + * 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 "CommunicationSocket.h" +#include "UtilConstants.h" +#include "StringUtil.h" + +#include +#include +#include +#include +#include + +#include + +#define BUFSIZE 1024 + +using namespace std; + +#define DEFAULT_BUFLEN 4096 + +CommunicationSocket::CommunicationSocket(int port) + : _port(port), _clientSocket(INVALID_SOCKET) +{ +} + +CommunicationSocket::~CommunicationSocket() +{ + Close(); +} + +bool CommunicationSocket::Close() +{ + WSACleanup(); + bool closed = (closesocket(_clientSocket) == 0); + shutdown(_clientSocket, SD_BOTH); + _clientSocket = INVALID_SOCKET; + return closed; +} + + +bool CommunicationSocket::Connect() +{ + WSADATA wsaData; + + HRESULT iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); + + if (iResult != NO_ERROR) { + int error = WSAGetLastError(); + } + + + _clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (_clientSocket == INVALID_SOCKET) { + //int error = WSAGetLastError(); + Close(); + return false; + } + + struct sockaddr_in clientService; + + clientService.sin_family = AF_INET; + clientService.sin_addr.s_addr = inet_addr(PLUG_IN_SOCKET_ADDRESS); + clientService.sin_port = htons(_port); + + iResult = connect(_clientSocket, (SOCKADDR*)&clientService, sizeof(clientService)); + + if (iResult == SOCKET_ERROR) { + //int error = WSAGetLastError(); + Close(); + return false; + } + return true; +} + +bool CommunicationSocket::SendMsg(const wchar_t* message) +{ + const char* utf8_msg = StringUtil::toUtf8(message); + size_t result = send(_clientSocket, utf8_msg, (int)strlen(utf8_msg), 0); + delete[] utf8_msg; + + if (result == SOCKET_ERROR) { + //int error = WSAGetLastError(); + closesocket(_clientSocket); + return false; + } + + return true; + +} + +bool CommunicationSocket::ReadLine(wstring* response) +{ + if (!response) { + return false; + } + + vector resp_utf8; + char buffer; + while (true) { + int bytesRead = recv(_clientSocket, &buffer, 1, 0); + if (bytesRead <= 0) { + response = 0; + return false; + } + + if (buffer == '\n') { + resp_utf8.push_back(0); + *response = StringUtil::toUtf16(&resp_utf8[0], resp_utf8.size()); + return true; + } else { + resp_utf8.push_back(buffer); + } + } +} diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.h b/shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.h new file mode 100644 index 000000000..7bbf1bf63 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/CommunicationSocket.h @@ -0,0 +1,42 @@ +/** + * 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. + */ + +#ifndef COMMUNICATIONSOCKET_H +#define COMMUNICATIONSOCKET_H + +#pragma once + +#pragma warning (disable : 4251) + +#include +#include + +class __declspec(dllexport) CommunicationSocket +{ +public: + CommunicationSocket(int port); + ~CommunicationSocket(); + + bool Connect(); + bool Close(); + + bool SendMsg(const wchar_t*); + bool ReadLine(std::wstring*); + +private: + int _port; + SOCKET _clientSocket; +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.cpp b/shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.cpp new file mode 100644 index 000000000..e0861682b --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.cpp @@ -0,0 +1,84 @@ +/** + * 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 "FileUtil.h" +#include "RegistryUtil.h" +#include "UtilConstants.h" + +using namespace std; + +bool FileUtil::IsChildFile(const wchar_t* rootFolder, vector* files) +{ + for(vector::iterator it = files->begin(); it != files->end(); it++) + { + wstring file = *it; + + size_t found = file.find(rootFolder); + + if(found != string::npos) + { + return true; + } + } + + return false; +} + +bool FileUtil::IsChildFile(const wchar_t* rootFolder, const wchar_t* file) +{ + wstring* f = new wstring(file); + + size_t found = f->find(rootFolder); + + if(found != string::npos) + { + return true; + } + + return false; +} + +bool FileUtil::IsChildFileOfRoot(std::vector* files) +{ + wstring* rootFolder = new wstring(); + bool needed = false; + + if(RegistryUtil::ReadRegistry(REGISTRY_ROOT_KEY, REGISTRY_FILTER_FOLDER, rootFolder)) + { + if(IsChildFile(rootFolder->c_str(), files)) + { + needed = true; + } + } + + delete rootFolder; + return needed; +} + +bool FileUtil::IsChildFileOfRoot(const wchar_t* filePath) +{ + wstring* rootFolder = new wstring(); + bool needed = false; + + if(RegistryUtil::ReadRegistry(REGISTRY_ROOT_KEY, REGISTRY_FILTER_FOLDER, rootFolder)) + { + if(FileUtil::IsChildFile(rootFolder->c_str(), filePath)) + { + needed = true; + } + } + + delete rootFolder; + return needed; +} \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.h b/shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.h new file mode 100644 index 000000000..650bc471f --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/FileUtil.h @@ -0,0 +1,40 @@ +/** + * 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. + */ + +#ifndef FILEUTIL_H +#define FILEUTIL_H + +#pragma once + +#pragma warning (disable : 4251) + +#include +#include + +class __declspec(dllexport) FileUtil +{ +public: + FileUtil(); + + ~FileUtil(); + + static bool IsChildFile(const wchar_t*, std::vector*); + static bool IsChildFile(const wchar_t*, const wchar_t*); + static bool IsChildFileOfRoot(std::vector*); + static bool IsChildFileOfRoot(const wchar_t*); + +private: +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.cpp b/shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.cpp new file mode 100644 index 000000000..b86005f71 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.cpp @@ -0,0 +1,74 @@ +/** + * 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 "OCMessage.h" +#include "ParserUtil.h" +#include "UtilConstants.h" + +#include + +#include +#include + +using namespace std; + +OCMessage::OCMessage(void) +{ + _command = new wstring(); + _value = new wstring(); +} + +OCMessage::~OCMessage(void) +{ +} + +bool OCMessage::InitFromMessage(const wstring* message) +{ + if(message->length() == 0) + { + return false; + } + + if(!ParserUtil::GetItem(COMMAND, message, _command)) + { + return false; + } + + if(!ParserUtil::GetItem(VALUE, message, _value)) + { + return false; + } + + return true; +} + +std::wstring* OCMessage::GetCommand() +{ + return _command; +} + +std::wstring* OCMessage::GetValue() +{ + return _value; +} + +void OCMessage::SetCommand(std::wstring* command) +{ + _command = command; +} + +void OCMessage::SetValue(std::wstring* value) +{ + _value = value; +} diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.h b/shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.h new file mode 100644 index 000000000..131f3d714 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/OCMessage.h @@ -0,0 +1,42 @@ +/** + * 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. + */ + +#ifndef OCMESSAGE_H +#define OCMESSAGE_H + +#include + +#pragma once + +class __declspec(dllexport) OCMessage +{ +public: + OCMessage(void); + ~OCMessage(void); + + bool InitFromMessage(const std::wstring*); + + std::wstring* GetCommand(); + std::wstring* GetValue(); + + void SetCommand(std::wstring*); + void SetValue(std::wstring*); + +private: + + std::wstring* _command; + std::wstring* _value; +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/OCUtil.vcxproj b/shell_integration/windows/OCShellExtensions/OCUtil/OCUtil.vcxproj new file mode 100644 index 000000000..fc3b1a31f --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/OCUtil.vcxproj @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {E4F63E19-808D-4234-8DF0-69C5F47C9CD3} + OCUtil + + + + DynamicLibrary + true + Unicode + v120_xp + + + DynamicLibrary + true + Unicode + v120_xp + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + .dll + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + $(ProjectName)_x86 + + + .dll + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + $(ProjectName)_x64 + + + $(ProjectName)_x64 + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + .dll + $(ProjectName)_x86 + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + + Level3 + Disabled + false + + + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + Disabled + + + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/ParserUtil.cpp b/shell_integration/windows/OCShellExtensions/OCUtil/ParserUtil.cpp new file mode 100644 index 000000000..ba7d9f101 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/ParserUtil.cpp @@ -0,0 +1,389 @@ +/** + * 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 "ParserUtil.h" +#include "UtilConstants.h" + +#include + +using namespace std; + +bool ParserUtil::GetItem(const wchar_t* item, const wstring* message, wstring* result) +{ + size_t start = message->find(item, 0); + + if(start == string::npos) + { + return false; + } + + size_t end = message->find(COLON, start); + + if(end == string::npos) + { + return false; + } + + //Move to next character after : + end += 1; + + wchar_t c = message->at(end); + + //Move to the next character, which is the start of the value + end += 1; + + if(c == '[') + { + return GetList(end - 1, message, result); + } + else + { + return GetValue(end, message, result); + } +} + +bool ParserUtil::GetList(size_t start, const wstring* message, wstring* result) +{ + size_t end = start + 1; + + int openBraceCount = 1; + + while(openBraceCount > 0) + { + size_t closeBraceLocation = message->find(CLOSE_BRACE, end); + size_t openBraceLocation = message->find(OPEN_BRACE, end); + + if(closeBraceLocation < openBraceLocation) + { + openBraceCount--; + end = closeBraceLocation + 1; + } + else if(openBraceLocation < closeBraceLocation) + { + openBraceCount++; + end = openBraceLocation + 1; + } + + } + + size_t length = end - start; + + return GetString(start, end, message, result); +} + +size_t ParserUtil::GetNextStringItemInList(const wstring* message, size_t start, wstring* result) +{ + size_t end = string::npos; + size_t commaLocation = message->find(COMMA, start); + + if(commaLocation == string::npos) + { + end = message->find(CLOSE_BRACE, start); + if(end == string::npos) + { + end = message->length(); + } + else + { + end = end - 1; + } + } + else + { + end = commaLocation - 1; + } + + if(!GetString(start + 2, end, message, result)) + { + return string::npos; + } + + return end + 2; +} + +size_t ParserUtil::GetNextOCItemInList(const wstring* message, size_t start, wstring* result) +{ + size_t end = message->find(OPEN_CURLY_BRACE, start) + 1; + + int openBraceCount = 1; + + while(openBraceCount > 0) + { + size_t closeBraceLocation = message->find(CLOSE_CURLY_BRACE, end); + size_t openBraceLocation = message->find(OPEN_CURLY_BRACE, end); + + if(closeBraceLocation < openBraceLocation) + { + openBraceCount--; + end = closeBraceLocation + 1; + } + else if(openBraceLocation < closeBraceLocation) + { + openBraceCount++; + end = openBraceLocation + 1; + } + } + + size_t length = end - start; + + if(!GetString(start, end, message, result)) + { + return string::npos; + } + + return end; +} + +bool ParserUtil::GetValue(size_t start, const wstring* message, wstring* result) +{ + if(message->at(start - 1) == '\"') + { + size_t end = message->find(QUOTE, start); + return GetString(start, end, message, result); + } + else + { + start = start - 1; + + size_t end = message->find(COMMA, start); + + result->append(message->substr(start, end-start)); + } + + return true; +} + +bool ParserUtil::GetString(size_t start, size_t end, const wstring* message, wstring* result) +{ + if(end == string::npos) + { + return false; + } + + size_t length = end - start; + + if(length > 0) + { + result->append(message->substr(start, length)); + } + else + { + result->append(L""); + } + + + return true; +} + +bool ParserUtil::IsList(wstring* message) +{ + wchar_t c = message->at(0); + + if(c == '[') + { + return true; + } + + return false; +} + +bool ParserUtil::ParseJsonList(wstring* message, vector* items) +{ + + size_t currentLocation = message->find(OPEN_BRACE, 0); + + while(currentLocation < message->size()) + { + wstring* item = new wstring(); + + currentLocation = ParserUtil::GetNextStringItemInList(message, currentLocation, item); + + if(currentLocation == string::npos) + { + return false; + } + + items->push_back(item); + } + + return true; +} + +bool ParserUtil::ParseOCList(wstring* message, vector* items) +{ + + size_t currentLocation = message->find(OPEN_CURLY_BRACE, 0); + + while(currentLocation < message->size()) + { + wstring* item = new wstring(); + + currentLocation = ParserUtil::GetNextOCItemInList(message, currentLocation, item); + + if(currentLocation == string::npos) + { + return false; + } + + items->push_back(item); + } + + return true; +} + +bool ParserUtil::ParseOCMessageList(wstring* message, vector* messages) +{ + vector* items = new vector(); + + if(!ParseOCList(message, items)) + { + return false; + } + + for(vector::iterator it = items->begin(); it != items->end(); it++) + { + wstring* temp = *it; + + OCMessage* message = new OCMessage(); + message->InitFromMessage(temp); + + messages->push_back(message); + } + + return true; +} + +bool ParserUtil::SerializeList(std::vector* list, std::wstring* result, bool escapeQuotes) +{ + if(result == 0) + { + return false; + } + + result->append(OPEN_BRACE); + + for(vector::iterator it = list->begin(); it != list->end(); it++) + { + wstring value = *it; + + if(escapeQuotes) + { + result->append(BACK_SLASH); + } + + result->append(QUOTE); + result->append(value.c_str()); + + if(escapeQuotes) + { + result->append(BACK_SLASH); + } + + result->append(QUOTE); + result->append(COMMA); + } + + //Erase last comma + result->erase(result->size() - 1, 1); + + result->append(CLOSE_BRACE); + + return true; +} + +bool ParserUtil::SerializeMessage(std::map* arguments, std::wstring* result, bool escapeQuotes) +{ + if(result == 0) + { + return false; + } + + result->append(OPEN_CURLY_BRACE); + + for(map::iterator it = arguments->begin(); it != arguments->end(); it++) + { + wstring key = *it->first; + wstring value = *it->second; + + if(escapeQuotes) + { + result->append(BACK_SLASH); + } + + result->append(QUOTE); + result->append(key.c_str()); + + if(escapeQuotes) + { + result->append(BACK_SLASH); + } + + result->append(QUOTE); + result->append(COLON); + result->append(value.c_str()); + result->append(COMMA); + } + + //Erase last comma + result->erase(result->size() - 1, 1); + + result->append(CLOSE_CURLY_BRACE); + + return true; +} + +bool ParserUtil::SerializeMessage(OCMessage* OCMessage, std::wstring* result) +{ + if(result == 0) + { + return false; + } + + result->append(OPEN_CURLY_BRACE); + + result->append(QUOTE); + result->append(COMMAND); + result->append(QUOTE); + + result->append(COLON); + + result->append(QUOTE); + result->append(OCMessage->GetCommand()->c_str()); + result->append(QUOTE); + + result->append(COMMA); + + result->append(QUOTE); + result->append(VALUE); + result->append(QUOTE); + + result->append(COLON); + + if(!IsList(OCMessage->GetValue())) + { + result->append(QUOTE); + } + + result->append(OCMessage->GetValue()->c_str()); + + if(!IsList(OCMessage->GetValue())) + { + result->append(QUOTE); + } + + result->append(CLOSE_CURLY_BRACE); + + return true; +} + diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.cpp b/shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.cpp new file mode 100644 index 000000000..5c41bf861 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.cpp @@ -0,0 +1,70 @@ +/** + * 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 "RegistryUtil.h" + +#include + +using namespace std; + +#define SIZE 4096 + +bool RegistryUtil::ReadRegistry(const wchar_t* key, const wchar_t* name, int* result) +{ + wstring* strResult = new wstring(); + + if(!ReadRegistry(key, name, strResult)) + { + return false; + } + + *result = stoi( strResult->c_str() ); + + return true; +} + +bool RegistryUtil::ReadRegistry(const wchar_t* key, const wchar_t* name, wstring* result) +{ + HRESULT hResult; + + HKEY rootKey = NULL; + + hResult = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key, NULL, KEY_READ, &rootKey)); + + if(!SUCCEEDED(hResult)) + { + return false; + } + + wchar_t value[SIZE]; + DWORD value_length = SIZE; + + hResult = RegQueryValueEx(rootKey, (LPCWSTR)name, NULL, NULL, (LPBYTE)value, &value_length ); + + if(!SUCCEEDED(hResult)) + { + return false; + } + + result->append(value); + + HRESULT hResult2 = RegCloseKey(rootKey); + + if (!SUCCEEDED(hResult2)) + { + return false; + } + + return true; +} diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.h b/shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.h new file mode 100644 index 000000000..1928d64ce --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/RegistryUtil.h @@ -0,0 +1,35 @@ +/** + * 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. + */ + +#ifndef REGISTRYUTIL_H +#define REGISTRYUTIL_H + +#pragma once + +#pragma warning (disable : 4251) + +#include + +class __declspec(dllexport) RegistryUtil +{ +public: + RegistryUtil(); + + ~RegistryUtil(); + + static bool ReadRegistry(const wchar_t*, const wchar_t*, int*); + static bool ReadRegistry(const wchar_t*, const wchar_t*, std::wstring*); +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.cpp b/shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.cpp new file mode 100644 index 000000000..2eec3c2ea --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.cpp @@ -0,0 +1,112 @@ +/** +* 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 +#include +#include +#include +#include + +using namespace std; + +namespace { + template + bool begins_with(const TContainer& input, const TContainer& match) + { + return input.size() >= match.size() + && equal(match.begin(), match.end(), input.begin()); + } +} + +RemotePathChecker::RemotePathChecker(int port) + : _port(port) +{ +} + +bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, bool isDir) +{ + wstring request; + wstring response; + bool needed = false; + + CommunicationSocket socket(_port); + socket.Connect(); + if (isDir) { + request = L"RETRIEVE_FOLDER_STATUS:"; + } else { + request = L"RETRIEVE_FILE_STATUS:"; + } + request += filePath; + request += L'\n'; + + if (!socket.SendMsg(request.c_str())) { + return false; + } + + while ((socket.ReadLine(&response))) { + // discard broadcast messages + if (begins_with(response, wstring(L"STATUS:"))) { + break; + } + } + + size_t statusBegin = response.find(L':', 0); + if (statusBegin == -1) + return false; + + size_t statusEnd = response.find(L':', statusBegin + 1); + if (statusEnd == -1) + return false; + + + 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) { + return false; + } + needed = true; + } + + return needed; +} + +int 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; +} \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.h b/shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.h new file mode 100644 index 000000000..5e58c6d64 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/RemotePathChecker.h @@ -0,0 +1,41 @@ +/** +* 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. +*/ + +#ifndef PATHCHECKER_H +#define PATHCHECKER_H + +#include + +#pragma once + +class __declspec(dllexport) RemotePathChecker { +public: + enum FileState { + // Order synced with OCOverlay + StateError = 0, StateErrorSWM, + StateOk, StateOkSWM, + StateSync, StateSyncSWM, + StateWarning, StateWarningSWM, + StateNone + }; + RemotePathChecker(int port); + bool IsMonitoredPath(const wchar_t* filePath, bool isDir); + +private: + int _StrToFileState(const std::wstring &str); + + int _port; + +}; + +#endif \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.cpp b/shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.cpp new file mode 100644 index 000000000..0c7af0b82 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.cpp @@ -0,0 +1,32 @@ +/** +* 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 + +#include "StringUtil.h" + +char* StringUtil::toUtf8(const wchar_t *utf16, int len) +{ + int newlen = WideCharToMultiByte(CP_UTF8, 0, utf16, len, NULL, 0, NULL, NULL); + char* str = new char[newlen]; + WideCharToMultiByte(CP_UTF8, 0, utf16, -1, str, newlen, NULL, NULL); + return str; +} + +wchar_t* StringUtil::toUtf16(const char *utf8, int len) +{ + int newlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); + wchar_t* wstr = new wchar_t[newlen]; + MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, newlen); + return wstr; +} diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.h b/shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.h new file mode 100644 index 000000000..d885a89f6 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/StringUtil.h @@ -0,0 +1,27 @@ +/** +* 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. +*/ + +#ifndef STRINGUTIL_H +#define STRINGUTIL_H + +#pragma once + +#include + +class __declspec(dllexport) StringUtil { +public: + static char* toUtf8(const wchar_t* utf16, int len = -1); + static wchar_t* toUtf16(const char* utf8, int len = -1); +}; + +#endif // STRINGUTIL_H diff --git a/shell_integration/windows/OCShellExtensions/OCUtil/UtilConstants.h b/shell_integration/windows/OCShellExtensions/OCUtil/UtilConstants.h new file mode 100644 index 000000000..04ca7d3ba --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtil/UtilConstants.h @@ -0,0 +1,30 @@ +/** + * 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. + */ + +#define PLUG_IN_SOCKET_ADDRESS "127.0.0.1" + +#define BACK_SLASH L"\\" +#define CLOSE_BRACE L"]" +#define CLOSE_CURLY_BRACE L"}" +#define COLON L":" +#define COMMAND L"command" +#define COMMA L"," +#define OPEN_BRACE L"[" +#define OPEN_CURLY_BRACE L"{" +#define QUOTE L"\"" +#define VALUE L"value" + +#define REGISTRY_ROOT_KEY L"SOFTWARE\\ownCloud Inc\\ownCloud" +#define REGISTRY_ENABLE_OVERLAY L"EnableOverlay" +#define REGISTRY_FILTER_FOLDER L"FilterFolder" diff --git a/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.cpp b/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.cpp new file mode 100644 index 000000000..179f8334a --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.cpp @@ -0,0 +1,37 @@ +// ConsoleApplication1.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +#include +#include +#include + +#include "RemotePathChecker.h" +#include "StringUtil.h" + +using namespace std; + +int _tmain(int argc, _TCHAR* argv[]) +{ + RemotePathChecker checker(33001); + + vector paths; + + wstring test1(L"C:\\Users\\owncloud\\ownCloud\\wizard2.png"); + wstring test2(L"C:\\Users\\owncloud\\ownCloud\\wizard3.png"); + wstring test3(L"C:\\Users\\owncloud\\ownCloud\\HAMMANET.png"); + paths.push_back(test1); + paths.push_back(test2); + paths.push_back(test3); + +// wstring test3 = StringUtil::toUtf16(StringUtil::toUtf8(test1.c_str())); + + vector::iterator it; + for (it = paths.begin(); it != paths.end(); ++it) { + bool monitored = checker.IsMonitoredPath(it->c_str(), false); + wcout << *it << " " << monitored << " with value " << checker.GetPathType() << endl; + } + return 0; +} + diff --git a/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.filters b/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.filters new file mode 100644 index 000000000..2507d8e20 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.vcxproj b/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.vcxproj new file mode 100644 index 000000000..e4c35a3b2 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtilTest/OCUtilTest.vcxproj @@ -0,0 +1,97 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {A81E3DAE-8FE7-4BD0-82F9-939B2D59D033} + Win32Proj + OCUtilTest + OCUtilTest + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + true + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + ..\OCUtil + + + Console + true + ..\$(Configuration)\$(Platform); + OCUtil_x86.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + Create + Create + + + + + + \ No newline at end of file diff --git a/shell_integration/windows/OCShellExtensions/OCUtilTest/ReadMe.txt b/shell_integration/windows/OCShellExtensions/OCUtilTest/ReadMe.txt new file mode 100644 index 000000000..4cb8a2f4b --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtilTest/ReadMe.txt @@ -0,0 +1,40 @@ +======================================================================== + CONSOLE APPLICATION : ConsoleApplication1 Project Overview +======================================================================== + +AppWizard has created this ConsoleApplication1 application for you. + +This file contains a summary of what you will find in each of the files that +make up your ConsoleApplication1 application. + + +ConsoleApplication1.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +ConsoleApplication1.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +ConsoleApplication1.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named ConsoleApplication1.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.cpp b/shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.cpp new file mode 100644 index 000000000..f1d63e0b4 --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// ConsoleApplication1.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.h b/shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.h new file mode 100644 index 000000000..b005a839d --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtilTest/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/shell_integration/windows/OCShellExtensions/OCUtilTest/targetver.h b/shell_integration/windows/OCShellExtensions/OCUtilTest/targetver.h new file mode 100644 index 000000000..87c0086de --- /dev/null +++ b/shell_integration/windows/OCShellExtensions/OCUtilTest/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include