+++ /dev/null
-// TortoiseSVN - a Windows shell extension for easy version control\r
-\r
-// Copyright (C) 2003-2008 - TortoiseSVN\r
-\r
-// This program is free software; you can redistribute it and/or\r
-// modify it under the terms of the GNU General Public License\r
-// as published by the Free Software Foundation; either version 2\r
-// of the License, or (at your option) any later version.\r
-\r
-// This program is distributed in the hope that it will be useful,\r
-// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-// GNU General Public License for more details.\r
-\r
-// You should have received a copy of the GNU General Public License\r
-// along with this program; if not, write to the Free Software Foundation,\r
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
-//\r
-#include "stdafx.h"\r
-\r
-#pragma warning (disable : 4786)\r
-\r
-// Initialize GUIDs (should be done only and at-least once per DLL/EXE)\r
-#include <initguid.h>\r
-#include "Guids.h"\r
-\r
-#include "ShellExt.h"\r
-//#include "..\version.h"\r
-//#include "libintl.h"\r
-#undef swprintf\r
-\r
-std::set<CShellExt *> g_exts;\r
-\r
-\r
-// *********************** CShellExt *************************\r
-CShellExt::CShellExt(FileState state)\r
-{\r
- OSVERSIONINFOEX inf;\r
- SecureZeroMemory(&inf, sizeof(OSVERSIONINFOEX));\r
- inf.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\r
- GetVersionEx((OSVERSIONINFO *)&inf);\r
- fullver = MAKEWORD(inf.dwMinorVersion, inf.dwMajorVersion);\r
-\r
- m_State = state;\r
-\r
- m_cRef = 0L;\r
- g_cRefThisDll++;\r
-\r
- g_exts.insert(this);\r
- \r
- INITCOMMONCONTROLSEX used = {\r
- sizeof(INITCOMMONCONTROLSEX),\r
- ICC_LISTVIEW_CLASSES | ICC_WIN95_CLASSES | ICC_BAR_CLASSES | ICC_USEREX_CLASSES\r
- };\r
- InitCommonControlsEx(&used);\r
- LoadLangDll();\r
-\r
- if (fullver >= 0x0600)\r
- {\r
- HMODULE hUxTheme = ::GetModuleHandle (_T("UXTHEME.DLL"));\r
-\r
- pfnGetBufferedPaintBits = (FN_GetBufferedPaintBits)::GetProcAddress(hUxTheme, "GetBufferedPaintBits");\r
- pfnBeginBufferedPaint = (FN_BeginBufferedPaint)::GetProcAddress(hUxTheme, "BeginBufferedPaint");\r
- pfnEndBufferedPaint = (FN_EndBufferedPaint)::GetProcAddress(hUxTheme, "EndBufferedPaint");\r
- }\r
-}\r
-\r
-CShellExt::~CShellExt()\r
-{\r
- std::map<UINT, HBITMAP>::iterator it;\r
- for (it = bitmaps.begin(); it != bitmaps.end(); ++it)\r
- {\r
- ::DeleteObject(it->second);\r
- }\r
- bitmaps.clear();\r
- g_cRefThisDll--;\r
- g_exts.erase(this);\r
-}\r
-\r
-void LoadLangDll()\r
-{\r
- if ((g_langid != g_ShellCache.GetLangID())&&((g_langTimeout == 0)||(g_langTimeout < GetTickCount())))\r
- {\r
- g_langid = g_ShellCache.GetLangID();\r
- DWORD langId = g_langid;\r
- TCHAR langDll[MAX_PATH*4];\r
- HINSTANCE hInst = NULL;\r
- TCHAR langdir[MAX_PATH] = {0};\r
- char langdirA[MAX_PATH] = {0};\r
- if (GetModuleFileName(g_hmodThisDll, langdir, MAX_PATH)==0)\r
- return;\r
- if (GetModuleFileNameA(g_hmodThisDll, langdirA, MAX_PATH)==0)\r
- return;\r
- TCHAR * dirpoint = _tcsrchr(langdir, '\\');\r
- char * dirpointA = strrchr(langdirA, '\\');\r
- if (dirpoint)\r
- *dirpoint = 0;\r
- if (dirpointA)\r
- *dirpointA = 0;\r
- dirpoint = _tcsrchr(langdir, '\\');\r
- dirpointA = strrchr(langdirA, '\\');\r
- if (dirpoint)\r
- *dirpoint = 0;\r
- if (dirpointA)\r
- *dirpointA = 0;\r
- strcat_s(langdirA, MAX_PATH, "\\Languages");\r
-// bindtextdomain ("subversion", langdirA);\r
-\r
- do\r
- {\r
- _stprintf_s(langDll, MAX_PATH*4, _T("%s\\Languages\\TortoiseProc%d.dll"), langdir, langId);\r
- BOOL versionmatch = TRUE;\r
-\r
- struct TRANSARRAY\r
- {\r
- WORD wLanguageID;\r
- WORD wCharacterSet;\r
- };\r
-\r
- DWORD dwReserved,dwBufferSize;\r
- dwBufferSize = GetFileVersionInfoSize((LPTSTR)langDll,&dwReserved);\r
-\r
- if (dwBufferSize > 0)\r
- {\r
- LPVOID pBuffer = (void*) malloc(dwBufferSize);\r
-\r
- if (pBuffer != (void*) NULL)\r
- {\r
- UINT nInfoSize = 0,\r
- nFixedLength = 0;\r
- LPSTR lpVersion = NULL;\r
- VOID* lpFixedPointer;\r
- TRANSARRAY* lpTransArray;\r
- TCHAR strLangProduktVersion[MAX_PATH];\r
-\r
- if (GetFileVersionInfo((LPTSTR)langDll,\r
- dwReserved,\r
- dwBufferSize,\r
- pBuffer))\r
- {\r
- // Query the current language\r
- if (VerQueryValue( pBuffer,\r
- _T("\\VarFileInfo\\Translation"),\r
- &lpFixedPointer,\r
- &nFixedLength))\r
- {\r
- lpTransArray = (TRANSARRAY*) lpFixedPointer;\r
-\r
- _stprintf_s(strLangProduktVersion, MAX_PATH, _T("\\StringFileInfo\\%04x%04x\\ProductVersion"),\r
- lpTransArray[0].wLanguageID, lpTransArray[0].wCharacterSet);\r
-\r
- if (VerQueryValue(pBuffer,\r
- (LPTSTR)strLangProduktVersion,\r
- (LPVOID *)&lpVersion,\r
- &nInfoSize))\r
- {\r
-// versionmatch = (_tcscmp((LPCTSTR)lpVersion, _T(STRPRODUCTVER)) == 0);\r
- }\r
-\r
- }\r
- }\r
- free(pBuffer);\r
- } // if (pBuffer != (void*) NULL) \r
- } // if (dwBufferSize > 0) \r
- else\r
- versionmatch = FALSE; \r
-\r
- if (versionmatch)\r
- hInst = LoadLibrary(langDll);\r
- if (hInst != NULL)\r
- {\r
- if (g_hResInst != g_hmodThisDll)\r
- FreeLibrary(g_hResInst);\r
- g_hResInst = hInst;\r
- }\r
- else\r
- {\r
- DWORD lid = SUBLANGID(langId);\r
- lid--;\r
- if (lid > 0)\r
- {\r
- langId = MAKELANGID(PRIMARYLANGID(langId), lid);\r
- }\r
- else\r
- langId = 0;\r
- } \r
- } while ((hInst == NULL) && (langId != 0));\r
- if (hInst == NULL)\r
- {\r
- // either the dll for the selected language is not present, or\r
- // it is the wrong version.\r
- // fall back to English and set a timeout so we don't retry\r
- // to load the language dll too often\r
- if (g_hResInst != g_hmodThisDll)\r
- FreeLibrary(g_hResInst);\r
- g_hResInst = g_hmodThisDll;\r
- g_langid = 1033;\r
- // set a timeout of 10 seconds\r
- if (g_ShellCache.GetLangID() != 1033)\r
- g_langTimeout = GetTickCount() + 10000;\r
- }\r
- else\r
- g_langTimeout = 0;\r
- } // if (g_langid != g_ShellCache.GetLangID()) \r
-}\r
-\r
-STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)\r
-{\r
- *ppv = NULL; \r
-\r
- if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown))\r
- {\r
- *ppv = (LPSHELLEXTINIT)this;\r
- }\r
- else if (IsEqualIID(riid, IID_IContextMenu))\r
- {\r
- *ppv = (LPCONTEXTMENU)this;\r
- }\r
- else if (IsEqualIID(riid, IID_IContextMenu2))\r
- {\r
- *ppv = (LPCONTEXTMENU2)this;\r
- }\r
- else if (IsEqualIID(riid, IID_IContextMenu3))\r
- {\r
- *ppv = (LPCONTEXTMENU3)this;\r
- }\r
- else if (IsEqualIID(riid, IID_IShellIconOverlayIdentifier))\r
- {\r
- *ppv = (IShellIconOverlayIdentifier*)this;\r
- }\r
- else if (IsEqualIID(riid, IID_IShellPropSheetExt))\r
- {\r
- *ppv = (LPSHELLPROPSHEETEXT)this;\r
- }\r
- else if (IsEqualIID(riid, IID_IColumnProvider)) \r
- { \r
- *ppv = (IColumnProvider *)this;\r
- } \r
- else if (IsEqualIID(riid, IID_IShellCopyHook))\r
- {\r
- *ppv = (ICopyHook *)this;\r
- }\r
- if (*ppv)\r
- {\r
- AddRef();\r
- \r
- return NOERROR;\r
- }\r
- \r
- return E_NOINTERFACE;\r
-}\r
-\r
-STDMETHODIMP_(ULONG) CShellExt::AddRef()\r
-{\r
- return ++m_cRef;\r
-}\r
-\r
-STDMETHODIMP_(ULONG) CShellExt::Release()\r
-{\r
- if (--m_cRef)\r
- return m_cRef;\r
- \r
- delete this;\r
- \r
- return 0L;\r
-}\r
-\r
-// IPersistFile members\r
-STDMETHODIMP CShellExt::GetClassID(CLSID *pclsid) \r
-{\r
- *pclsid = CLSID_Tortoisegit_UNCONTROLLED;\r
- return S_OK;\r
-}\r
-\r
-STDMETHODIMP CShellExt::Load(LPCOLESTR /*pszFileName*/, DWORD /*dwMode*/)\r
-{\r
- return S_OK;\r
-}\r
-\r
-// ICopyHook member\r
-UINT __stdcall CShellExt::CopyCallback(HWND /*hWnd*/, UINT wFunc, UINT /*wFlags*/, LPCTSTR pszSrcFile, DWORD /*dwSrcAttribs*/, LPCTSTR /*pszDestFile*/, DWORD /*dwDestAttribs*/)\r
-{\r
- if (wFunc == FO_COPY)\r
- return IDYES; // copying is not a problem for us\r
-\r
-// m_remoteCacheLink.ReleaseLockForPath(CTSVNPath(pszSrcFile));\r
- // we could now wait a little bit to give the cache time to release the handles.\r
- // but the explorer/shell already retries any action for about two seconds\r
- // if it first fails. So if the cache hasn't released the handle yet, the explorer\r
- // will retry anyway, so we just leave here immediately.\r
- return IDYES;\r
-}\r
-// CShellExt member functions (needed for IShellPropSheetExt)\r
-STDMETHODIMP CShellExt::AddPages (LPFNADDPROPSHEETPAGE lpfnAddPage,\r
- LPARAM lParam)\r
-{\r
-#if 0\r
- for (std::vector<stdstring>::iterator I = files_.begin(); I != files_.end(); ++I)\r
- {\r
- GitStatus svn = GitStatus();\r
- if (svn.GetStatus(CTGitPath(I->c_str())) == (-2))\r
- return NOERROR; // file/directory not under version control\r
-\r
- if (svn.status->entry == NULL)\r
- return NOERROR;\r
- }\r
-\r
- if (files_.size() == 0)\r
- return NOERROR;\r
-\r
- LoadLangDll();\r
- PROPSHEETPAGE psp;\r
- SecureZeroMemory(&psp, sizeof(PROPSHEETPAGE));\r
- HPROPSHEETPAGE hPage;\r
- CGitPropertyPage *sheetpage = new CGitPropertyPage(files_);\r
-\r
- psp.dwSize = sizeof (psp);\r
- psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USEICONID | PSP_USECALLBACK; \r
- psp.hInstance = g_hResInst;\r
- psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE);\r
- psp.pszIcon = MAKEINTRESOURCE(IDI_APPSMALL);\r
- psp.pszTitle = _T("Subversion");\r
- psp.pfnDlgProc = (DLGPROC) PageProc;\r
- psp.lParam = (LPARAM) sheetpage;\r
- psp.pfnCallback = PropPageCallbackProc;\r
- psp.pcRefParent = &g_cRefThisDll;\r
-\r
- hPage = CreatePropertySheetPage (&psp);\r
-\r
- if (hPage != NULL)\r
- {\r
- if (!lpfnAddPage (hPage, lParam))\r
- {\r
- delete sheetpage;\r
- DestroyPropertySheetPage (hPage);\r
- }\r
- }\r
-#endif\r
- return NOERROR;\r
-}\r
-\r
-\r
-\r
-STDMETHODIMP CShellExt::ReplacePage (UINT /*uPageID*/, LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/, LPARAM /*lParam*/)\r
-{\r
- return E_FAIL;\r
-}\r
-\r