Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in tip

fogcreek shellext: reimplement COM objects using ATL

Changeset 2f829ff70272

Parent d001f17422b2

by David Golub

Changes to 23 files · Browse files at 2f829ff70272 Showing diff from parent d001f17422b2 Diff from another changeset...

 
1
 
2
3
4
5
6
7
8
9
10
11
 
125
126
127
128
 
129
130
131
 
167
168
169
170
 
171
172
173
 
297
298
299
300
 
301
302
303
 
381
382
383
384
 
385
386
387
 
398
399
400
401
 
402
403
404
 
563
564
565
566
 
567
568
569
 
591
592
593
594
 
595
596
597
 
717
718
719
720
 
721
722
723
 
725
726
727
728
 
729
730
731
 
775
776
777
778
 
779
780
781
 
867
868
869
870
 
871
872
873
 
905
906
907
908
 
909
910
911
 
972
973
974
975
 
976
977
978
979
980
981
982
983
984
985
 
986
987
988
989
990
 
1
2
3
4
5
6
7
8
 
9
10
11
 
125
126
127
 
128
129
130
131
 
167
168
169
 
170
171
172
173
 
297
298
299
 
300
301
302
303
 
381
382
383
 
384
385
386
387
 
398
399
400
 
401
402
403
404
 
563
564
565
 
566
567
568
569
 
591
592
593
 
594
595
596
597
 
717
718
719
 
720
721
722
723
 
725
726
727
 
728
729
730
731
 
775
776
777
 
778
779
780
781
 
867
868
869
 
870
871
872
873
 
905
906
907
 
908
909
910
911
 
972
973
974
 
975
976
 
 
 
 
 
977
978
 
 
979
980
 
981
 
 
@@ -1,11 +1,11 @@
 #include "stdafx.h" +#include "THgShell_h.h"  #include "TortoiseUtils.h"  #include "StringUtils.h"  #include "Thgstatus.h"  #include "Winstat.h"  #include "InitStatus.h"  #include "SysInfo.h" -#include "ShellExt.h"  #include "RegistryConfig.h"  #include "TortoiseIconBitmap.h"  #include "ThgVersion.h" @@ -125,7 +125,7 @@
 ;     -void CShellExtCMenu::AddMenuList(UINT idCmd, const std::string& name) +void CShellExtCMenuBase::AddMenuList(UINT idCmd, const std::string& name)  {   TDEBUG_TRACE("AddMenuList: idCmd = " << idCmd << " name = " << name);   myMenuIdMap[idCmd] = myDescMap[name]; @@ -167,7 +167,7 @@
  RegCloseKey(hkey);  }   -void CShellExtCMenu::InitMenuMaps(const MenuDescription *menuDescs, std::size_t sz) +void CShellExtCMenuBase::InitMenuMaps(const MenuDescription *menuDescs, std::size_t sz)  {   if (myDescMap.empty())   { @@ -297,7 +297,7 @@
 }     -void CShellExtCMenu::InsertMenuItemByName( +void CShellExtCMenuBase::InsertMenuItemByName(   HMENU hMenu, const std::string& name, UINT indexMenu,   UINT idCmd, UINT idCmdFirst, const std::wstring& prefix)  { @@ -381,7 +381,7 @@
 }    void -CShellExtCMenu::TweakMenuForVista(HMENU hMenu) +CShellExtCMenuBase::TweakMenuForVista(HMENU hMenu)  {   if (!SysInfo::Instance().IsVistaOrLater())   return; @@ -398,7 +398,7 @@
   // IContextMenu  STDMETHODIMP -CShellExtCMenu::QueryContextMenu( +CShellExtCMenuBase::QueryContextMenu(   HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)  {   TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu"); @@ -563,7 +563,7 @@
     STDMETHODIMP -CShellExtCMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) +CShellExtCMenuBase::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)  {   TDEBUG_TRACE("CShellExtCMenu::InvokeCommand");   @@ -591,7 +591,7 @@
     STDMETHODIMP -CShellExtCMenu::GetCommandString( +CShellExtCMenuBase::GetCommandString(   UINT_PTR idCmd, UINT uFlags, UINT FAR *reserved,   LPSTR pszName, UINT cchMax)  { @@ -717,7 +717,7 @@
     STDMETHODIMP -CShellExtCMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) +CShellExtCMenuBase::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)  {   LRESULT res;   return HandleMenuMsg2(uMsg, wParam, lParam, &res); @@ -725,7 +725,7 @@
     STDMETHODIMP -CShellExtCMenu::HandleMenuMsg2( +CShellExtCMenuBase::HandleMenuMsg2(   UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pResult)  {   // A great tutorial on owner drawn menus in shell extension can be found @@ -775,7 +775,7 @@
 }     -void CShellExtCMenu::RunDialog(const std::string &cmd) +void CShellExtCMenuBase::RunDialog(const std::string &cmd)  {   std::string dir = GetTHgProgRoot();   if (dir.empty()) @@ -867,7 +867,7 @@
  InitStatus::check();  }   -void CShellExtCMenu::PrintDebugHeader(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj) +void CShellExtCMenuBase::PrintDebugHeader(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj)  {   TDEBUG_TRACE("CShellExtCMenu::Initialize");   @@ -905,7 +905,7 @@
  TDEBUG_TRACE(" pDataObj: " << pDataObj);  }   -STDMETHODIMP CShellExtCMenu::Initialize( +STDMETHODIMP CShellExtCMenuBase::Initialize(   LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey)  {   TCHAR name[MAX_PATH+1]; @@ -972,19 +972,10 @@
 }     -CShellExtCMenu::CShellExtCMenu(const char dummy) +CShellExtCMenuBase::CShellExtCMenuBase()  { - CShellExt::IncDllRef(); - ADDIFACE(IShellExtInit); - ADDIFACE(IContextMenu); - ADDIFACE(IContextMenu2); - ADDIFACE(IContextMenu3);  }   - -CShellExtCMenu::~CShellExtCMenu() +CShellExtCMenu::CShellExtCMenu()  { - CShellExt::DecDllRef();  } - -IMPLEMENT_UNKNOWN(CShellExtCMenu)
 
5
6
7
8
9
10
11
12
 
21
22
23
24
 
 
 
 
25
26
27
28
29
30
31
 
42
43
44
45
46
 
47
48
 
 
 
 
 
 
49
50
51
 
64
65
66
 
 
 
 
 
 
 
 
 
67
68
 
5
6
7
 
 
8
9
10
 
19
20
21
 
22
23
24
25
26
 
27
 
28
29
30
 
41
42
43
 
 
44
45
 
46
47
48
49
50
51
52
53
54
 
67
68
69
70
71
72
73
74
75
76
77
78
79
80
@@ -5,8 +5,6 @@
 #include <string>  #include <map>   -#include "SimpleUnknown.h" -  struct MenuDescription  {   std::string name; @@ -21,11 +19,12 @@
 typedef std::map<UINT, MenuDescription> MenuIdCmdMap;     -class CShellExtCMenu: public CSimpleUnknown, IContextMenu3, IShellExtInit +class CShellExtCMenuBase : + public CComObjectRootEx<CComMultiThreadModel>, + public IContextMenu3, + public IShellExtInit  { -  protected: - ULONG m_cRef;   std::vector<std::string> myFiles;   std::string myFolder;   MenuDescriptionMap myDescMap; @@ -42,10 +41,14 @@
  void AddMenuList(UINT idCmd, const std::string& name);    public: - explicit CShellExtCMenu(const char dummy); - ~CShellExtCMenu(); + CShellExtCMenuBase();   - DECLARE_UNKNOWN() + BEGIN_COM_MAP(CShellExtCMenuBase) + COM_INTERFACE_ENTRY(IContextMenu) + COM_INTERFACE_ENTRY(IContextMenu2) + COM_INTERFACE_ENTRY(IContextMenu3) + COM_INTERFACE_ENTRY(IShellExtInit) + END_COM_MAP()     // IContextMenu3   STDMETHOD(QueryContextMenu)( @@ -64,5 +67,14 @@
  LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hKeyID);  };   +class CShellExtCMenu : + public CShellExtCMenuBase, + public CComCoClass<CShellExtCMenu, &CLSID_TortoiseHgCmenu> +{ +public: + CShellExtCMenu(); + + DECLARE_REGISTRY_RESOURCE(IDR_CMENU) +};    #endif
Change 1 of 1 Show Entire File win32/​shellext/​CShellExtCMenu.rgs Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
@@ -0,0 +1,13 @@
+HKCR +{ + NoRemove CLSID + { + ForceRemove {46605027-5B8C-4DCE-BFE0-051B7972D64C} = s 'TortoiseHg' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +}
 
1
 
2
3
4
 
77
78
79
80
 
81
82
83
 
163
164
165
166
167
 
168
169
170
 
1
2
3
4
5
 
78
79
80
 
81
82
83
84
 
164
165
166
 
 
167
168
169
170
@@ -1,4 +1,5 @@
 #include "stdafx.h" +#include "THgShell_h.h"  #include "TortoiseUtils.h"    #include "CShellExtDnd.h" @@ -77,7 +78,7 @@
  //Append the current directory as the dest   myFiles.push_back(myFolder);   } - CShellExtCMenu::RunDialog(cmd); + CShellExtCMenuBase::RunDialog(cmd);  }     @@ -163,8 +164,7 @@
 }     -CShellExtDnd::CShellExtDnd(const char dummy) : - CShellExtCMenu(dummy) +CShellExtDnd::CShellExtDnd()  {  }  
 
4
5
6
7
8
 
 
 
9
10
11
12
13
14
15
 
16
17
 
 
18
19
20
 
4
5
6
 
 
7
8
9
10
11
12
13
14
15
 
16
17
18
19
20
21
22
23
@@ -4,17 +4,20 @@
 #include "CShellExtCMenu.h"     -//CShellExtCMenu implements IContextMenu3, IShellExtInit -class CShellExtDnd: public CShellExtCMenu +// CShellExtCMenuBase implements IContextMenu3, IShellExtInit +class CShellExtDnd : public CShellExtCMenuBase, + public CComCoClass<CShellExtDnd, &CLSID_TortoiseHgDropHandler>  {    protected:   virtual void RunDialog(const std::string&);    public: - explicit CShellExtDnd(const char dummy); + explicit CShellExtDnd();   ~CShellExtDnd();   + DECLARE_REGISTRY_RESOURCE(IDR_DRAGDROP) +   // IContextMenu3   STDMETHOD(QueryContextMenu)(   HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast,
Change 1 of 1 Show Entire File win32/​shellext/​CShellExtDnd.rgs Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
@@ -0,0 +1,13 @@
+HKCR +{ + NoRemove CLSID + { + ForceRemove {CEBD95BE-B733-415F-82A8-673D9158466E} = s 'TortoiseHg' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +}
 
1
2
 
3
4
5
6
7
8
9
10
 
11
12
13
 
30
31
32
33
 
34
35
36
 
77
78
79
80
81
82
83
84
85
86
87
88
89
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
3
4
5
6
7
8
 
 
9
10
11
12
 
29
30
31
 
32
33
34
35
 
76
77
78
 
 
79
80
 
81
82
 
83
84
 
 
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
@@ -1,13 +1,12 @@
 #include "stdafx.h" -#include "ShellExt.h" +#include "THgShell_h.h"  #include "TortoiseUtils.h"  #include "StringUtils.h"  #include "QueryDirstate.h"  #include "RegistryConfig.h"  #include "CShellExtOverlay.h"   -#include <shlwapi.h> - +CComAutoCriticalSection CShellExtOverlay::m_cs;    STDMETHODIMP CShellExtOverlay::GetOverlayInfo(   LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags) @@ -30,7 +29,7 @@
   STDMETHODIMP CShellExtOverlay::IsMemberOf(LPCWSTR pwszPath, DWORD /* dwAttrib */)  { - ThgCriticalSection cs(CShellExt::GetCriticalSection()); + CComCritSecLock<CComAutoCriticalSection> lock(m_cs);     std::string cval;   if (GetRegistryConfig("EnableOverlays", cval) != 0 && cval == "0") @@ -77,14 +76,28 @@
 CShellExtOverlay::CShellExtOverlay(char tortoiseClass) :   myTortoiseClass(tortoiseClass)  { - CShellExt::IncDllRef(); - ADDIFACE(IShellIconOverlayIdentifier);  }   -  CShellExtOverlay::~CShellExtOverlay()  { - CShellExt::DecDllRef();  }   -IMPLEMENT_UNKNOWN(CShellExtOverlay) \ No newline at end of file
+CTortoiseHgNormal::CTortoiseHgNormal() : + CShellExtOverlay('C') +{ +} + +CTortoiseHgAdded::CTortoiseHgAdded() : + CShellExtOverlay('A') +{ +} + +CTortoiseHgModified::CTortoiseHgModified() : + CShellExtOverlay('M') +{ +} + +CTortoiseHgUnversioned::CTortoiseHgUnversioned() : + CShellExtOverlay('?') +{ +}
 
1
2
3
4
 
 
 
 
 
5
6
7
8
9
10
11
12
13
14
 
 
 
15
16
17
 
20
21
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24
 
1
2
3
 
4
5
6
7
8
9
 
 
10
11
12
13
14
15
 
16
17
18
19
20
21
 
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@@ -1,17 +1,21 @@
 #ifndef _CShellExtOverlay_h_  #define _CShellExtOverlay_h_   -#include "SimpleUnknown.h" +class CShellExtOverlay : + public CComObjectRootEx<CComMultiThreadModel>, + public IShellIconOverlayIdentifier +{ + static CComAutoCriticalSection m_cs;   -class CShellExtOverlay: public CSimpleUnknown, public IShellIconOverlayIdentifier -{   const char myTortoiseClass;    public:   explicit CShellExtOverlay(char Class);   ~CShellExtOverlay();   - DECLARE_UNKNOWN() + BEGIN_COM_MAP(CShellExtOverlay) + COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier) + END_COM_MAP()     // IShellIconOverlayIdentifier   STDMETHOD(GetOverlayInfo)( @@ -20,5 +24,44 @@
  STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);  };   +class CTortoiseHgNormal : + public CShellExtOverlay, + public CComCoClass<CTortoiseHgNormal, &CLSID_TortoiseHgNormal> +{ +public: + CTortoiseHgNormal(); + + DECLARE_REGISTRY_RESOURCE(IDR_NORMAL) +}; + +class CTortoiseHgAdded : + public CShellExtOverlay, + public CComCoClass<CTortoiseHgAdded, &CLSID_TortoiseHgAdded> +{ +public: + CTortoiseHgAdded(); + + DECLARE_REGISTRY_RESOURCE(IDR_ADDED) +}; + +class CTortoiseHgModified : + public CShellExtOverlay, + public CComCoClass<CTortoiseHgModified, &CLSID_TortoiseHgNormal> +{ +public: + CTortoiseHgModified(); + + DECLARE_REGISTRY_RESOURCE(IDR_MODIFIED) +}; + +class CTortoiseHgUnversioned : + public CShellExtOverlay, + public CComCoClass<CTortoiseHgUnversioned, &CLSID_TortoiseHgNormal> +{ +public: + CTortoiseHgUnversioned(); + + DECLARE_REGISTRY_RESOURCE(IDR_UNVERSIONED) +};    #endif
 
1
 
 
 
 
2
3
4
5
6
7
8
9
10
11
 
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
 
 
 
 
 
 
 
39
40
41
42
43
44
45
46
47
 
48
49
50
51
52
53
 
54
55
56
57
58
59
60
61
62
63
 
64
65
66
67
 
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
 
133
134
135
136
137
138
139
140
141
142
143
 
1
2
3
4
5
6
7
8
9
 
10
11
12
 
13
14
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
 
 
30
31
32
33
34
 
 
35
36
37
38
39
40
 
41
42
43
 
44
45
46
 
 
47
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
50
 
 
 
 
 
 
 
 
 
 
@@ -1,143 +1,50 @@
 #include "stdafx.h" +#include <initguid.h> +#include "THgShell_h.h" +#include "THgShell_i.c" +  #include "ShellExt.h"  #include "TortoiseUtils.h"  #include "StringUtils.h"  #include "InitStatus.h" -#include "ThgClassFactory.h"  #include "CShellExtCMenu.h"  #include "CShellExtDnd.h"  #include "CShellExtOverlay.h" -#include "ThgCLSIDs.h"   +CComModule _Module;   -#define TOLSTR(x) L ## #x -#define TOLSTR2(x) TOLSTR(x) - -#define CLSID_TortoiseHgCmenu TOLSTR2(THG_CLSID_TortoiseHgCmenu) -#define CLSID_TortoiseHgDropHandler TOLSTR2(THG_CLSID_TortoiseHgDropHandler) -#define CLSID_TortoiseHgNormal TOLSTR2(THG_CLSID_TortoiseHgNormal) -#define CLSID_TortoiseHgAdded TOLSTR2(THG_CLSID_TortoiseHgAdded) -#define CLSID_TortoiseHgModified TOLSTR2(THG_CLSID_TortoiseHgModified) -#define CLSID_TortoiseHgUnversioned TOLSTR2(THG_CLSID_TortoiseHgUnversioned) - -CRITICAL_SECTION CShellExt::cs_; -HMODULE CShellExt::hModule_ = NULL; -UINT CShellExt::cRef_ = 0; - -typedef struct -{ - HKEY hRootKey; - LPTSTR lpszSubKey; - LPTSTR lpszValueName; - LPTSTR lpszData; -} REGSTRUCT, *LPREGSTRUCT; - - -VOID _LoadResources(); -VOID _UnloadResources(); - +BEGIN_OBJECT_MAP(ObjectMap) + OBJECT_ENTRY(CLSID_TortoiseHgCmenu, CShellExtCMenu) + OBJECT_ENTRY(CLSID_TortoiseHgDropHandler, CShellExtDnd) + OBJECT_ENTRY(CLSID_TortoiseHgNormal, CTortoiseHgNormal) + OBJECT_ENTRY(CLSID_TortoiseHgAdded, CTortoiseHgAdded) + OBJECT_ENTRY(CLSID_TortoiseHgModified, CTortoiseHgModified) + OBJECT_ENTRY(CLSID_TortoiseHgUnversioned, CTortoiseHgUnversioned) +END_OBJECT_MAP()    BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)  {   if (dwReason == DLL_PROCESS_ATTACH)   {   TDEBUG_TRACE("DllMain: DLL_PROCESS_ATTACH"); - CShellExt::hModule_ = hInstance; - ::InitializeCriticalSection(CShellExt::GetCriticalSection()); - _LoadResources(); + _Module.Init(ObjectMap, hInstance, &LIBID_THgShell);   }   else if (dwReason == DLL_PROCESS_DETACH)   {   TDEBUG_TRACE("DllMain: DLL_PROCESS_ATTACH"); - ::DeleteCriticalSection(CShellExt::GetCriticalSection()); - _UnloadResources(); + _Module.Term();   }     return 1;  }   -  STDAPI DllCanUnloadNow(void)  {   TDEBUG_TRACE("DllCanUnloadNow"); - return (CShellExt::GetRefCount() == 0 ? S_OK : S_FALSE); + return _Module.GetLockCount() == 0 ? S_OK : S_FALSE;  }   - -STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut) +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)  { - std::wstring clsid; - { - LPWSTR ptr = 0; - ::StringFromIID(rclsid, &ptr); - clsid = ptr; - ::CoTaskMemFree(ptr); - } - - TDEBUG_TRACEW("DllGetClassObject clsid = " << clsid); - - if (ppvOut == 0) - { - TDEBUG_TRACE("**** DllGetClassObject: error: ppvOut is 0"); - return E_POINTER; - } - - *ppvOut = NULL; - - typedef ThgClassFactory<CShellExtOverlay> FactOvl; - typedef ThgClassFactory<CShellExtCMenu> FactCmenu; - typedef ThgClassFactory<CShellExtDnd> FactDnd; - - if (clsid == CLSID_TortoiseHgCmenu) - { - FactCmenu *pcf = new FactCmenu(0); - TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgCmenu"); - return pcf->QueryInterface(riid, ppvOut); - } - else if (clsid == CLSID_TortoiseHgDropHandler) - { - FactDnd *pcf = new FactDnd(0); - TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgDropHandler"); - return pcf->QueryInterface(riid, ppvOut); - } - else if (clsid == CLSID_TortoiseHgNormal) - { - FactOvl *pcf = new FactOvl('C'); // clean - TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgNormal"); - ++InitStatus::inst().unchanged_; - return pcf->QueryInterface(riid, ppvOut); - } - else if (clsid == CLSID_TortoiseHgAdded) - { - FactOvl *pcf = new FactOvl('A'); // added - TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgAdded"); - ++InitStatus::inst().added_; - return pcf->QueryInterface(riid, ppvOut); - } - else if (clsid == CLSID_TortoiseHgModified) - { - FactOvl *pcf = new FactOvl('M'); // modified - TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgModified"); - ++InitStatus::inst().modified_; - return pcf->QueryInterface(riid, ppvOut); - } - else if (clsid == CLSID_TortoiseHgUnversioned) - { - FactOvl *pcf = new FactOvl('?'); // not in repo - TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgUnversioned"); - ++InitStatus::inst().notinrepo_; - return pcf->QueryInterface(riid, ppvOut); - } - - return CLASS_E_CLASSNOTAVAILABLE; + return _Module.GetClassObject(rclsid, riid, ppv);  } - - -VOID _LoadResources(VOID) -{ -} - - -VOID _UnloadResources(VOID) -{ -}
Change 1 of 1 Show Entire File win32/​shellext/​ShellExt.h Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -1,38 +0,0 @@
-#ifndef _SHELL_EXT_H_ -#define _SHELL_EXT_H_ - - -class CShellExt -{ - static CRITICAL_SECTION cs_; - static HMODULE hModule_; - static UINT cRef_; - -public: - static LPCRITICAL_SECTION GetCriticalSection() { return &cs_; } - static UINT GetRefCount() { return cRef_; } - static void IncDllRef() { ::InterlockedIncrement(&cRef_); } - static void DecDllRef() { ::InterlockedDecrement(&cRef_); } - - friend BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID); -}; - - -class ThgCriticalSection -{ - LPCRITICAL_SECTION cs_; - -public: - ThgCriticalSection(LPCRITICAL_SECTION cs): cs_(cs) - { - ::EnterCriticalSection(cs_); - } - - ~ThgCriticalSection() - { - ::LeaveCriticalSection(cs_); - } -}; - - -#endif // _SHELL_EXT_H_
Change 1 of 1 Show Entire File win32/​shellext/​SimpleUnknown.cpp Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -1,65 +0,0 @@
-// Copyright (C) 2011 Fog Creek Software -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "stdafx.h" - -#include "SimpleUnknown.h" - -CSimpleUnknown::CSimpleUnknown() - : cRef_(0) -{ - AddInterface(IID_IUnknown, this); -} - -CSimpleUnknown::~CSimpleUnknown() -{ -} - -void CSimpleUnknown::AddInterface(REFIID riid, LPUNKNOWN punk) -{ - Entry e(riid, punk); - entries_.push_back(e); -} - -STDMETHODIMP CSimpleUnknown::QueryInterface(REFIID riid, LPVOID FAR* ppv) -{ - if (ppv == NULL) - return E_POINTER; - - for (EntriesT::const_iterator i = entries_.begin(); i != entries_.end(); ++i) - { - if (i->iid == riid) - { - i->punk->AddRef(); - *ppv = i->punk; - return S_OK; - } - } - *ppv = NULL; - return E_NOINTERFACE; -} - -STDMETHODIMP_(ULONG) CSimpleUnknown::AddRef() -{ - return ::InterlockedIncrement(&cRef_); -} - -STDMETHODIMP_(ULONG) CSimpleUnknown::Release() -{ - if (::InterlockedDecrement(&cRef_)) - return cRef_; - delete this; - return 0L; -}
Change 1 of 1 Show Entire File win32/​shellext/​SimpleUnknown.h Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -1,81 +0,0 @@
-// Copyright (C) 2011 Fog Creek Software -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#ifndef _SIMPLEUNKNOWN_H_ -#define _SIMPLEUNKNOWN_H_ - -#include <vector> - -#define DECLARE_UNKNOWN() \ - STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR* ppv); \ - STDMETHOD_(ULONG, AddRef)(); \ - STDMETHOD_(ULONG, Release)(); \ - -#define IMPLEMENT_UNKNOWN(classname) \ - STDMETHODIMP classname::QueryInterface(REFIID riid, LPVOID FAR* ppv) \ - { \ - return CSimpleUnknown::QueryInterface(riid, ppv); \ - } \ - STDMETHODIMP_(ULONG) classname::AddRef() \ - { \ - return CSimpleUnknown::AddRef(); \ - } \ - STDMETHODIMP_(ULONG) classname::Release() \ - { \ - return CSimpleUnknown::Release(); \ - } - -#define INLINE_UNKNOWN() \ - STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppv) \ - { \ - return CSimpleUnknown::QueryInterface(riid, ppv); \ - } \ - STDMETHODIMP_(ULONG) AddRef() \ - { \ - return CSimpleUnknown::AddRef(); \ - } \ - STDMETHODIMP_(ULONG) Release() \ - { \ - return CSimpleUnknown::Release(); \ - } - -#define ADDIFACE(iface) \ - AddInterface(IID_##iface, (iface*)this) - -class CSimpleUnknown : public IUnknown -{ - struct Entry - { - Entry(IID iid, LPUNKNOWN punk): iid(iid), punk(punk) {} - IID iid; - LPUNKNOWN punk; - }; - - typedef std::vector<Entry> EntriesT; - - EntriesT entries_; - UINT cRef_; - -protected: - void AddInterface(REFIID riid, IUnknown* punk); - -public: - CSimpleUnknown(); - virtual ~CSimpleUnknown(); - - DECLARE_UNKNOWN() -}; - -#endif
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
16
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@@ -1,17 +1,17 @@
-// Copyright (C) 2011 Fog Creek Software -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. +// Copyright (C) 2011 Fog Creek Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>.    import "objidl.idl";  import "shobjidl.idl";
 
217
218
219
220
221
222
223
 
240
241
242
243
244
 
245
246
247
248
249
250
251
252
 
255
256
257
 
 
258
 
 
 
 
259
260
261
 
217
218
219
 
220
221
222
 
239
240
241
 
 
242
243
244
245
 
 
246
247
248
 
251
252
253
254
255
256
257
258
259
260
261
262
263
@@ -217,7 +217,6 @@
  <ClCompile Include="QueryDirstate.cpp" />   <ClCompile Include="RegistryConfig.cpp" />   <ClCompile Include="ShellExt.cpp" /> - <ClCompile Include="SimpleUnknown.cpp" />   <ClCompile Include="StringUtils.cpp" />   <ClCompile Include="SysInfo.cpp" />   <ClCompile Include="ThgDebug.cpp" /> @@ -240,13 +239,10 @@
  <ClInclude Include="InitStatus.h" />   <ClInclude Include="QueryDirstate.h" />   <ClInclude Include="RegistryConfig.h" /> - <ClInclude Include="ShellExt.h" /> - <ClInclude Include="SimpleUnknown.h" /> + <ClInclude Include="resource.h" />   <ClInclude Include="stdafx.h" />   <ClInclude Include="StringUtils.h" />   <ClInclude Include="SysInfo.h" /> - <ClInclude Include="ThgClassFactory.h" /> - <ClInclude Include="ThgCLSIDs.h" />   <ClInclude Include="ThgDebug.h" />   <ClInclude Include="Thgstatus.h" />   <ClInclude Include="ThgVersion.h" /> @@ -255,7 +251,13 @@
  <ClInclude Include="Winstat.h" />   </ItemGroup>   <ItemGroup> + <None Include="CShellExtCMenu.rgs" /> + <None Include="CShellExtDnd.rgs" />   <None Include="ShellExt.def" /> + <None Include="TortoiseHgAdded.rgs" /> + <None Include="TortoiseHgModified.rgs" /> + <None Include="TortoiseHgNormal.rgs" /> + <None Include="TortoiseHgUnversioned.rgs" />   </ItemGroup>   <ItemGroup>   <ResourceCompile Include="shellext.rc" />
 
54
55
56
57
58
59
60
61
62
 
119
120
121
122
123
124
125
126
127
128
129
130
 
134
135
136
137
138
139
140
141
142
143
144
145
 
158
159
160
 
 
 
161
162
163
164
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
167
168
 
54
55
56
 
 
 
57
58
59
 
116
117
118
 
 
 
 
 
 
119
120
121
 
125
126
127
 
 
 
 
 
 
128
129
130
 
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
@@ -54,9 +54,6 @@
  <ClCompile Include="ShellExt.cpp">   <Filter>Source Files</Filter>   </ClCompile> - <ClCompile Include="SimpleUnknown.cpp"> - <Filter>Source Files</Filter> - </ClCompile>   <ClCompile Include="StringUtils.cpp">   <Filter>Source Files</Filter>   </ClCompile> @@ -119,12 +116,6 @@
  <ClInclude Include="RegistryConfig.h">   <Filter>Header Files</Filter>   </ClInclude> - <ClInclude Include="ShellExt.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="SimpleUnknown.h"> - <Filter>Header Files</Filter> - </ClInclude>   <ClInclude Include="stdafx.h">   <Filter>Header Files</Filter>   </ClInclude> @@ -134,12 +125,6 @@
  <ClInclude Include="SysInfo.h">   <Filter>Header Files</Filter>   </ClInclude> - <ClInclude Include="ThgClassFactory.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ThgCLSIDs.h"> - <Filter>Header Files</Filter> - </ClInclude>   <ClInclude Include="ThgDebug.h">   <Filter>Header Files</Filter>   </ClInclude> @@ -158,11 +143,32 @@
  <ClInclude Include="Winstat.h">   <Filter>Header Files</Filter>   </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude>   </ItemGroup>   <ItemGroup>   <None Include="ShellExt.def">   <Filter>Source Files</Filter>   </None> + <None Include="CShellExtCMenu.rgs"> + <Filter>Resource Files</Filter> + </None> + <None Include="CShellExtDnd.rgs"> + <Filter>Resource Files</Filter> + </None> + <None Include="TortoiseHgAdded.rgs"> + <Filter>Resource Files</Filter> + </None> + <None Include="TortoiseHgModified.rgs"> + <Filter>Resource Files</Filter> + </None> + <None Include="TortoiseHgNormal.rgs"> + <Filter>Resource Files</Filter> + </None> + <None Include="TortoiseHgUnversioned.rgs"> + <Filter>Resource Files</Filter> + </None>   </ItemGroup>   <ItemGroup>   <ResourceCompile Include="shellext.rc">
Change 1 of 1 Show Entire File win32/​shellext/​ThgCLSIDs.h Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -1,12 +0,0 @@
-#ifndef _THGCLSID_H_ -#define _THGCLSID_H_ - -#define THG_CLSID_TortoiseHgCmenu {46605027-5B8C-4DCE-BFE0-051B7972D64C} -#define THG_CLSID_TortoiseHgDropHandler {CEBD95BE-B733-415F-82A8-673D9158466E} -#define THG_CLSID_TortoiseHgNormal {869C8877-2C3C-438D-844B-31B86BFE5E8A} -#define THG_CLSID_TortoiseHgAdded {AF42ADAB-8C2E-4285-B746-99B31094708E} -#define THG_CLSID_TortoiseHgModified {CDA1C89D-E9B5-4981-A857-82DD932EA2FD} -#define THG_CLSID_TortoiseHgUnversioned {9E3D4EC9-0624-4393-8B48-204C217ED1FF} - - -#endif
Change 1 of 1 Show Entire File win32/​shellext/​ThgClassFactory.h Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -1,59 +0,0 @@
-#ifndef _ThgClassFactory_h_ -#define _ThgClassFactory_h_ - -#include "ShellExt.h" -#include "SimpleUnknown.h" - -template <class T> -class ThgClassFactory: public CSimpleUnknown, public IClassFactory -{ - const char myclassToMake; - -public: - explicit ThgClassFactory(char classToMake) : - myclassToMake(classToMake) - { - CShellExt::IncDllRef(); - ADDIFACE(IClassFactory); - } - - - ~ThgClassFactory() - { - CShellExt::DecDllRef(); - } - - INLINE_UNKNOWN() - - STDMETHODIMP CreateInstance( - LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppvObj) - { - if (ppvObj == 0) - return E_POINTER; - - *ppvObj = NULL; - - if (pUnkOuter) - return CLASS_E_NOAGGREGATION; - - T *pShellExt = new T(myclassToMake); - if (NULL == pShellExt) - return E_OUTOFMEMORY; - - const HRESULT hr = pShellExt->QueryInterface(riid, ppvObj); - if (FAILED(hr)) - delete pShellExt; - - return hr; - } - - - STDMETHODIMP LockServer(BOOL fLock) - { - return S_OK; - } - -}; - - -#endif
Change 1 of 1 Show Entire File win32/​shellext/​TortoiseHgAdded.rgs Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
@@ -0,0 +1,13 @@
+HKCR +{ + NoRemove CLSID + { + ForceRemove {AF42ADAB-8C2E-4285-B746-99B31094708E} = s 'TortoiseHg' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +}
Change 1 of 1 Show Entire File win32/​shellext/​TortoiseHgModified.rgs Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
@@ -0,0 +1,13 @@
+HKCR +{ + NoRemove CLSID + { + ForceRemove {CDA1C89D-E9B5-4981-A857-82DD932EA2FD} = s 'TortoiseHg' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +}
Change 1 of 1 Show Entire File win32/​shellext/​TortoiseHgNormal.rgs Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
@@ -0,0 +1,13 @@
+HKCR +{ + NoRemove CLSID + { + ForceRemove {869C8877-2C3C-438D-844B-31B86BFE5E8A} = s 'TortoiseHg' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +}
Change 1 of 1 Show Entire File win32/​shellext/​TortoiseHgUnversioned.rgs Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
@@ -0,0 +1,13 @@
+HKCR +{ + NoRemove CLSID + { + ForceRemove {9E3D4EC9-0624-4393-8B48-204C217ED1FF} = s 'TortoiseHg' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +}
 
1
2
 
 
 
 
 
 
 
 
 
 
3
4
5
 
69
70
71
72
73
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
79
80
81
 
 
@@ -1,5 +1,15 @@
 #include "windows.h"  #include "parentid.h" +#include "resource.h" + +1 TYPELIB "THgShell.tlb" + +IDR_CMENU REGISTRY "CShellExtCMenu.rgs" +IDR_DRAGDROP REGISTRY "CShellExtDnd.rgs" +IDR_NORMAL REGISTRY "TortoiseHgNormal.rgs" +IDR_ADDED REGISTRY "TortoiseHgAdded.rgs" +IDR_MODIFIED REGISTRY "TortoiseHgModified.rgs" +IDR_UNVERSIONED REGISTRY "TortoiseHgUnversioned.rgs"    #ifndef THG_VERSION_FIRST  /* dummy version for shellext development */ @@ -69,5 +79,3 @@
  VALUE "Translation", 0x409, 1200   END  END - -1 TYPELIB "THgShell.tlb"
 
9
10
11
12
13
 
 
 
 
 
14
15
16
17
18
19
 
9
10
11
 
 
12
13
14
15
16
17
18
 
19
20
21
@@ -9,11 +9,13 @@
  */  #define WINVER 0x0500 // need to enable hbmpItem member in MENUITEMINFO   -#include <windows.h> -#include <windowsx.h> +#include "resource.h" + +#include <atlbase.h> +extern CComModule _Module; +#include <atlcom.h>  #include <shlobj.h>  #include <assert.h> -#include <tchar.h>  #include <string>    #include "ThgDebug.h"