Update diff del rename ignore document.
[TortoiseGit.git] / src / TortoiseShell / TortoiseStub.c
blob57bdba021ae325944fdcabb4cf8b45da1f2fcf79
1 // TortoiseSVN - a Windows shell extension for easy version control
3 // Copyright (C) 2007 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #define _WIN32_WINNT 0x0400
20 #include <Windows.h>
21 #include <tchar.h>
22 #include "Debug.h"
25 const HINSTANCE NIL = (HINSTANCE)((char*)(0)-1);
27 static HINSTANCE hInst = NULL;
29 static HINSTANCE hTortoiseSVN = NULL;
30 static LPFNGETCLASSOBJECT pDllGetClassObject = NULL;
31 static LPFNCANUNLOADNOW pDllCanUnloadNow = NULL;
36 /**
37 * \ingroup TortoiseShell
38 * Check whether to load the full TortoiseSVN.dll or not.
40 static BOOL WantRealVersion(void)
42 static const WCHAR TSVNRootKey[]=_T("Software\\TortoiseSVN");
43 static const WCHAR ExplorerOnlyValue[]=_T("LoadDllOnlyInExplorer");
45 static const WCHAR ExplorerEnvPath[]=_T("%SystemRoot%\\explorer.exe");
48 DWORD bExplorerOnly = 0;
49 WCHAR ModuleName[MAX_PATH] = {0};
50 WCHAR ExplorerPath[MAX_PATH] = {0};
52 HKEY hKey = HKEY_CURRENT_USER;
53 LONG Result = ERROR;
54 DWORD Type = REG_DWORD;
55 DWORD Len = sizeof(DWORD);
57 BOOL bWantReal = TRUE;
60 TRACE(_T("WantRealVersion() - Enter\n"));
62 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TSVNRootKey, 0, KEY_READ, &hKey);
63 if (Result == ERROR_SUCCESS)
65 Result = RegQueryValueEx(hKey, ExplorerOnlyValue, NULL, &Type, (BYTE *)&bExplorerOnly, &Len);
66 if ((Result == ERROR_SUCCESS) && (Type == REG_DWORD) && (Len == sizeof(DWORD)) && bExplorerOnly)
68 TRACE(_T("WantRealVersion() - Explorer Only\n"));
70 // check if the current process is in fact the explorer
71 Len = GetModuleFileName(NULL, ModuleName, sizeof(ModuleName));
72 if (Len)
74 TRACE(_T("Process is %s\n"), ModuleName);
76 Len = ExpandEnvironmentStrings(ExplorerEnvPath, ExplorerPath, sizeof(ExplorerPath));
77 if (Len && (Len <= sizeof(ExplorerPath)))
79 TRACE(_T("Explorer path is %s\n"), ExplorerPath);
80 bWantReal = !lstrcmpi(ModuleName, ExplorerPath);
85 RegCloseKey(hKey);
88 TRACE(_T("WantRealVersion() - Exit\n"));
89 return bWantReal;
92 static void LoadRealLibrary(void)
94 static const char GetClassObject[] = "DllGetClassObject";
95 static const char CanUnloadNow[] = "DllCanUnloadNow";
97 WCHAR ModuleName[MAX_PATH] = {0};
98 DWORD Len = 0;
101 if (hTortoiseSVN)
102 return;
104 if (!WantRealVersion())
106 TRACE(_T("LoadRealLibrary() - Bypass\n"));
107 hTortoiseSVN = NIL;
108 return;
111 Len = GetModuleFileName(hInst, ModuleName, sizeof(ModuleName));
112 if (!Len)
114 TRACE(_T("LoadRealLibrary() - Fail\n"));
115 hTortoiseSVN = NIL;
116 return;
119 // truncate the string at the last '\' char
120 while(Len > 0)
122 --Len;
123 if (ModuleName[Len] == '\\')
125 ModuleName[Len] = '\0';
126 break;
129 if (Len == 0)
131 TRACE(_T("LoadRealLibrary() - Fail\n"));
132 hTortoiseSVN = NIL;
133 return;
135 lstrcat(ModuleName, _T("\\TortoiseSVN.dll"));
137 TRACE(_T("LoadRealLibrary() - Load %s\n"), ModuleName);
139 hTortoiseSVN = LoadLibraryEx(ModuleName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
140 if (!hTortoiseSVN)
142 TRACE(_T("LoadRealLibrary() - Fail\n"));
143 hTortoiseSVN = NIL;
144 return;
147 TRACE(_T("LoadRealLibrary() - Success\n"));
148 pDllGetClassObject = NULL;
149 pDllCanUnloadNow = NULL;
150 pDllGetClassObject = (LPFNGETCLASSOBJECT)GetProcAddress(hTortoiseSVN, GetClassObject);
151 if (pDllGetClassObject == NULL)
153 TRACE(_T("LoadRealLibrary() - Fail\n"));
154 FreeLibrary(hTortoiseSVN);
155 hTortoiseSVN = NIL;
156 return;
158 pDllCanUnloadNow = (LPFNCANUNLOADNOW)GetProcAddress(hTortoiseSVN, CanUnloadNow);
159 if (pDllCanUnloadNow == NULL)
161 TRACE(_T("LoadRealLibrary() - Fail\n"));
162 FreeLibrary(hTortoiseSVN);
163 hTortoiseSVN = NIL;
164 return;
168 static void UnloadRealLibrary(void)
170 if (!hTortoiseSVN)
171 return;
173 if (hTortoiseSVN != NIL)
174 FreeLibrary(hTortoiseSVN);
176 hTortoiseSVN = NULL;
177 pDllGetClassObject = NULL;
178 pDllCanUnloadNow = NULL;
182 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
184 #ifdef _DEBUG
185 // if no debugger is present, then don't load the dll.
186 // this prevents other apps from loading the dll and locking
187 // it.
189 BOOL bInShellTest = FALSE;
190 TCHAR buf[_MAX_PATH + 1]; // MAX_PATH ok, the test really is for debugging anyway.
191 DWORD pathLength = GetModuleFileName(NULL, buf, _MAX_PATH);
193 UNREFERENCED_PARAMETER(Reserved);
195 if (pathLength >= 14)
197 if ((lstrcmpi(&buf[pathLength-14], _T("\\ShellTest.exe"))) == 0)
199 bInShellTest = TRUE;
203 if (!IsDebuggerPresent() && !bInShellTest)
205 TRACE(_T("In debug load preventer\n"));
206 return FALSE;
208 #else
209 UNREFERENCED_PARAMETER(Reserved);
210 #endif
213 switch(Reason)
215 case DLL_PROCESS_ATTACH:
216 hInst = hInstance;
217 break;
219 //case DLL_THREAD_ATTACH:
220 // break;
222 //case DLL_THREAD_DETACH:
223 // break;
225 //case DLL_PROCESS_DETACH:
226 // break;
229 return TRUE;
233 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
235 TRACE(_T("DllGetClassObject() - Enter\n"));
237 LoadRealLibrary();
238 if (!pDllGetClassObject)
240 if (ppv)
241 *ppv = NULL;
242 else
243 ppv = NULL;
245 TRACE(_T("DllGetClassObject() - Bypass\n"));
246 return CLASS_E_CLASSNOTAVAILABLE;
249 TRACE(_T("DllGetClassObject() - Forward\n"));
250 return pDllGetClassObject(rclsid, riid, ppv);
253 STDAPI DllCanUnloadNow(void)
255 HRESULT Result;
257 TRACE(_T("DllCanUnloadNow() - Enter\n"));
259 if (pDllCanUnloadNow)
261 TRACE(_T("DllCanUnloadNow() - Forward\n"));
262 Result = pDllCanUnloadNow();
263 if (Result != S_OK)
264 return Result;
267 TRACE(_T("DllCanUnloadNow() - Unload\n"));
268 UnloadRealLibrary();
269 return S_OK;