1
// TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2018-2023 - TortoiseGit
4 // Copyright (C) 2003-2012, 2014, 2021-2022 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include <wrl/client.h>
25 #include "ShellCache.h"
26 #include "RemoteCacheLink.h"
27 #include "GitStatus.h"
28 #include "GitFolderStatus.h"
29 #include "IconBitmapUtils.h"
31 #include "ExplorerCommand.h"
33 class CExplorerCommand
;
34 extern volatile LONG g_cRefThisDll
; // Reference count of this DLL.
35 extern HINSTANCE g_hmodThisDll
; // Instance handle for this DLL
36 extern ShellCache g_ShellCache
; // caching of registry entries, ...
37 extern DWORD g_langid
;
38 extern ULONGLONG g_langTimeout
;
39 extern HINSTANCE g_hResInst
;
40 extern std::wstring g_filepath
;
41 extern git_wc_status_kind g_filestatus
; ///< holds the corresponding status to the file/dir above
42 extern bool g_readonlyoverlay
; ///< whether to show the read only overlay or not
43 extern bool g_lockedoverlay
; ///< whether to show the locked overlay or not
45 extern bool g_normalovlloaded
;
46 extern bool g_modifiedovlloaded
;
47 extern bool g_conflictedovlloaded
;
48 extern bool g_readonlyovlloaded
;
49 extern bool g_deletedovlloaded
;
50 extern bool g_lockedovlloaded
;
51 extern bool g_addedovlloaded
;
52 extern bool g_ignoredovlloaded
;
53 extern bool g_unversionedovlloaded
;
54 extern LPCWSTR g_MenuIDString
;
56 extern void LoadLangDll();
57 extern CComCriticalSection g_csGlobalCOMGuard
;
58 using AutoLocker
= CComCritSecLock
<CComCriticalSection
>;
60 // The actual OLE Shell context menu handler
62 * \ingroup TortoiseShell
63 * The main class of our COM object / Shell Extension.
64 * It contains all Interfaces we implement for the shell to use.
65 * \remark The implementations of the different interfaces are
66 * split into several *.cpp files to keep them in a reasonable size.
68 class CShellExt
: public IContextMenu3
,
71 IShellIconOverlayIdentifier
,
77 friend class CExplorerCommand
;
81 FileState m_State
= FileStateInvalid
;
82 volatile ULONG m_cRef
= 0;
83 //std::map<int,std::string> verbMap;
84 std::map
<UINT_PTR
, UINT_PTR
> myIDMap
;
85 std::map
<UINT_PTR
, UINT_PTR
> mySubMenuMap
;
86 std::map
<std::wstring
, UINT_PTR
> myVerbsMap
;
87 std::map
<UINT_PTR
, std::wstring
> myVerbsIDMap
;
89 std::vector
<std::wstring
> files_
;
90 DWORD itemStates
= 0; ///< see the globals.h file for the ITEMIS_* defines
91 DWORD itemStatesFolder
= 0; ///< used for states of the folder_ (folder background and/or drop target folder)
92 std::wstring uuidSource
;
93 std::wstring uuidTarget
;
95 wchar_t stringtablebuffer
[255]{};
96 std::wstring ignoredprops
;
97 CRegStdString regDiffLater
;
99 GitFolderStatus m_CachedStatus
; // status cache
100 CRemoteCacheLink m_remoteCacheLink
;
101 IconBitmapUtils m_iconBitmapUtils
;
102 Microsoft::WRL::ComPtr
<IUnknown
> m_site
;
103 std::vector
<Microsoft::WRL::ComPtr
<CExplorerCommand
>> m_explorerCommands
;
105 #define MAKESTRING(ID) LoadStringEx(g_hResInst, ID, stringtablebuffer, _countof(stringtablebuffer), static_cast<WORD>(CRegStdDWORD(L"Software\\TortoiseGit\\LanguageID", MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT))))
107 void InsertGitMenu(BOOL istop
, HMENU menu
, UINT pos
, UINT_PTR id
, UINT stringid
, UINT icon
, UINT idCmdFirst
, GitCommands com
, UINT uFlags
);
108 bool InsertLFSSubmenu(UINT
& idCmd
, UINT idCmdFirst
, HMENU hMenu
, HMENU subMenu
, UINT
& indexMenu
, int& indexSubMenu
, unsigned __int64 topmenu
, bool bShowIcons
, UINT uFlags
);
109 bool InsertIgnoreSubmenus(UINT
&idCmd
, UINT idCmdFirst
, HMENU hMenu
, HMENU subMenu
, UINT
&indexMenu
, int &indexSubMenu
, unsigned __int64 topmenu
, bool bShowIcons
, UINT uFlags
);
110 static std::wstring
WriteFileListToTempFile(bool bFoldersOnly
, const std::vector
<std::wstring
>& files
, const std::wstring folder
);
111 static bool WriteClipboardPathsToTempFile(std::wstring
& tempfile
);
112 LPCWSTR
GetMenuTextFromResource(int id
);
113 bool ShouldInsertItem(const MenuInfo
& pair
) const;
114 bool ShouldEnableMenu(const YesNoPair
& pair
) const;
115 void TweakMenu(HMENU menu
);
116 static void AddPathCommand(std::wstring
& gitCmd
, LPCWSTR command
, bool bFilesAllowed
, const std::vector
<std::wstring
>& files
, const std::wstring folder
);
117 static void AddPathFileCommand(std::wstring
& gitCmd
, LPCWSTR command
, const std::vector
<std::wstring
>& files
, const std::wstring folder
, bool bFoldersOnly
);
118 static void AddPathFileDropCommand(std::wstring
& gitCmd
, LPCWSTR command
, const std::vector
<std::wstring
>& files
, const std::wstring folder
);
119 STDMETHODIMP
QueryDropContext(UINT uFlags
, UINT idCmdFirst
, HMENU hMenu
, UINT
&indexMenu
);
120 bool IsIllegalFolder(const std::wstring
& folder
);
121 static void RunCommand(const std::wstring
& path
, const std::wstring
& command
, LPCWSTR errorMessage
, Microsoft::WRL::ComPtr
<IUnknown
> site
);
122 static void InvokeCommand(int cmd
, const std::wstring
& appDir
, const std::wstring uuidSource
, HWND hParent
, DWORD itemStates
, DWORD itemStatesFolder
, const std::vector
<std::wstring
>& paths
, const std::wstring
& folder
, CRegStdString
& regDiffLater
, Microsoft::WRL::ComPtr
<IUnknown
> site
);
123 static std::wstring
ExplorerViewPath(const Microsoft::WRL::ComPtr
<IUnknown
>& site
);
125 CShellExt(FileState state
);
126 virtual ~CShellExt();
132 STDMETHODIMP
QueryInterface(REFIID
, LPVOID FAR
*) override
;
133 STDMETHODIMP_(ULONG
) AddRef() override
;
134 STDMETHODIMP_(ULONG
) Release() override
;
137 /** \name IContextMenu2
138 * IContextMenu2 members
141 STDMETHODIMP
QueryContextMenu(HMENU hMenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
) override
;
142 STDMETHODIMP
InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
) override
;
143 STDMETHODIMP
GetCommandString(UINT_PTR idCmd
, UINT uFlags
, UINT FAR
*reserved
, LPSTR pszName
, UINT cchMax
) override
;
144 STDMETHODIMP
HandleMenuMsg(UINT uMsg
, WPARAM wParam
, LPARAM lParam
) override
;
147 /** \name IContextMenu3
148 * IContextMenu3 members
151 STDMETHODIMP
HandleMenuMsg2(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*pResult
) override
;
154 /** \name IShellExtInit
155 * IShellExtInit methods
158 STDMETHODIMP
Initialize(LPCITEMIDLIST pIDFolder
, LPDATAOBJECT pDataObj
, HKEY hKeyID
) override
;
161 /** \name IPersistFile
162 * IPersistFile methods
165 STDMETHODIMP
GetClassID(CLSID
*pclsid
) override
;
166 STDMETHODIMP
Load(LPCOLESTR pszFileName
, DWORD dwMode
) override
;
167 STDMETHODIMP
IsDirty() override
{ return S_OK
; };
168 STDMETHODIMP
Save(LPCOLESTR
/*pszFileName*/, BOOL
/*fRemember*/) override
{ return S_OK
; };
169 STDMETHODIMP
SaveCompleted(LPCOLESTR
/*pszFileName*/) override
{ return S_OK
; };
170 STDMETHODIMP
GetCurFile(LPOLESTR
* /*ppszFileName*/) override
{ return S_OK
; };
173 /** \name IShellIconOverlayIdentifier
174 * IShellIconOverlayIdentifier methods
177 STDMETHODIMP
GetOverlayInfo(LPWSTR pwszIconFile
, int cchMax
, int *pIndex
, DWORD
*pdwFlags
) override
;
178 STDMETHODIMP
GetPriority(int *pPriority
) override
;
179 STDMETHODIMP
IsMemberOf(LPCWSTR pwszPath
, DWORD dwAttrib
) override
;
182 /** \name IShellPropSheetExt
183 * IShellPropSheetExt methods
186 STDMETHODIMP
AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage
, LPARAM lParam
) override
;
187 STDMETHODIMP
ReplacePage (UINT
, LPFNADDPROPSHEETPAGE
, LPARAM
) override
;
194 STDMETHODIMP_(UINT
) CopyCallback(HWND hWnd
, UINT wFunc
, UINT wFlags
, LPCWSTR pszSrcFile
, DWORD dwSrcAttribs
, LPCWSTR pszDestFile
, DWORD dwDestAttribs
) override
;
197 /** \name IExplorerCommand
198 * IExplorerCommand members
201 HRESULT STDMETHODCALLTYPE
GetTitle(IShellItemArray
* psiItemArray
, LPWSTR
* ppszName
) override
;
202 HRESULT STDMETHODCALLTYPE
GetIcon(IShellItemArray
* psiItemArray
, LPWSTR
* ppszIcon
) override
;
203 HRESULT STDMETHODCALLTYPE
GetToolTip(IShellItemArray
* psiItemArray
, LPWSTR
* ppszInfotip
) override
;
204 HRESULT STDMETHODCALLTYPE
GetCanonicalName(GUID
* pguidCommandName
) override
;
205 HRESULT STDMETHODCALLTYPE
GetState(IShellItemArray
* psiItemArray
, BOOL fOkToBeSlow
, EXPCMDSTATE
* pCmdState
) override
;
206 HRESULT STDMETHODCALLTYPE
Invoke(IShellItemArray
* psiItemArray
, IBindCtx
* pbc
) override
;
207 HRESULT STDMETHODCALLTYPE
GetFlags(EXPCMDFLAGS
* pFlags
) override
;
208 HRESULT STDMETHODCALLTYPE
EnumSubCommands(IEnumExplorerCommand
** ppEnum
) override
;
211 /** \name IObjectWithSite
212 * IObjectWithSite members
215 HRESULT STDMETHODCALLTYPE
SetSite(IUnknown
* pUnkSite
) override
;
216 HRESULT STDMETHODCALLTYPE
GetSite(REFIID riid
, void** ppvSite
) override
;