Refactored: More information hiding
[TortoiseGit.git] / src / Utils / Libraries.cpp
blob48292957b8f78cf7aa957dae0780d8a9abc80a63
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2010-2011 - 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 #include "stdafx.h"
20 #include "Libraries.h"
21 #include "PathUtils.h"
22 #include "resource.h"
23 #include <initguid.h>
24 #include <propkeydef.h>
25 #if (NTDDI_VERSION < 0x06010000)
27 #define INITGUID
29 #ifdef _WIN64
30 // {DC9E616B-7611-461c-9D37-730FDD4CE278}
31 DEFINE_GUID(FOLDERTYPEID_GITWC, 0xdc9e616b, 0x7611, 0x461c, 0x9d, 0x37, 0x73, 0xf, 0xdd, 0x4c, 0xe2, 0x78);
32 // {B118C031-A977-4a67-9344-47F057388105}
33 DEFINE_GUID(FOLDERTYPEID_GITWC32, 0xb118c031, 0xa977, 0x4a67, 0x93, 0x44, 0x47, 0xf0, 0x57, 0x38, 0x81, 0x5);
34 #else
35 DEFINE_GUID(FOLDERTYPEID_GITWC, 0xb118c031, 0xa977, 0x4a67, 0x93, 0x44, 0x47, 0xf0, 0x57, 0x38, 0x81, 0x5);
36 #endif
38 #endif /* (NTDDI_VERSION < NTDDI_WIN7) */
40 #include "StdAfx.h"
41 #include "Libraries.h"
42 #include "win7.h"
43 #include "SmartHandle.h"
45 /**
46 * Makes sure a library named "Subversion" exists and has our template
47 * set to it.
48 * If the library already exists, the template is set.
49 * If the library doesn't exist, it is created.
51 void EnsureGitLibrary(bool bCreate /* = true*/)
53 // when running the 32-bit version of TortoiseProc on x64 OS,
54 // we must not create the library! This would break
55 // the library in the x64 explorer.
56 BOOL bIsWow64 = FALSE;
57 IsWow64Process(GetCurrentProcess(), &bIsWow64);
58 if (bIsWow64)
59 return;
61 CComPtr<IShellLibrary> pLibrary = NULL;
62 if (FAILED(OpenShellLibrary(L"Git", &pLibrary)))
64 if (!bCreate)
65 return;
66 if (FAILED(SHCreateLibrary(IID_PPV_ARGS(&pLibrary))))
67 return;
69 // Save the new library under the user's Libraries folder.
70 CComPtr<IShellItem> pSavedTo = NULL;
71 if (FAILED(pLibrary->SaveInKnownFolder(FOLDERID_UsersLibraries, L"Git", LSF_OVERRIDEEXISTING, &pSavedTo)))
72 return;
75 if (SUCCEEDED(pLibrary->SetFolderType(FOLDERTYPEID_GITWC)))
77 // create the path for the icon
78 CString path;
79 CString appDir = CPathUtils::GetAppDirectory();
80 if (appDir.GetLength() < MAX_PATH)
82 TCHAR buf[MAX_PATH] = {0};
83 PathCanonicalize(buf, (LPCTSTR)appDir);
84 appDir = buf;
86 path.Format(_T("%s%s,-%d"), (LPCTSTR)appDir, _T("TortoiseGitProc.exe"), IDI_LIBRARY);
87 pLibrary->SetIcon((LPCTSTR)path);
88 pLibrary->Commit();
92 /**
93 * Open the shell library under the user's Libraries folder according to the
94 * specified library name with both read and write permissions.
96 * \param pwszLibraryName
97 * The name of the shell library to be opened.
99 * \param ppShellLib
100 * If the open operation succeeds, ppShellLib outputs the IShellLibrary
101 * interface of the shell library object. The caller is responsible for calling
102 * Release on the shell library. If the function fails, NULL is returned from
103 * *ppShellLib.
105 HRESULT OpenShellLibrary(LPWSTR pwszLibraryName, IShellLibrary** ppShellLib)
107 HRESULT hr;
108 *ppShellLib = NULL;
110 IShellItem2* pShellItem = NULL;
111 hr = GetShellLibraryItem(pwszLibraryName, &pShellItem);
112 if (FAILED(hr))
113 return hr;
115 // Get the shell library object from the shell item with a read and write permissions
116 hr = SHLoadLibraryFromItem(pShellItem, STGM_READWRITE, IID_PPV_ARGS(ppShellLib));
118 pShellItem->Release();
120 return hr;
124 * Get the shell item that represents the library.
126 * \param pwszLibraryName
127 * The name of the shell library
129 * \param ppShellItem
130 * If the operation succeeds, ppShellItem outputs the IShellItem2 interface
131 * that represents the library. The caller is responsible for calling
132 * Release on the shell item. If the function fails, NULL is returned from
133 * *ppShellItem.
135 HRESULT GetShellLibraryItem(LPWSTR pwszLibraryName, IShellItem2** ppShellItem)
137 HRESULT hr = E_NOINTERFACE;
138 *ppShellItem = NULL;
140 // Create the real library file name
141 WCHAR wszRealLibraryName[MAX_PATH];
142 swprintf_s(wszRealLibraryName, L"%s%s", pwszLibraryName, L".library-ms");
144 typedef HRESULT STDAPICALLTYPE SHCreateItemInKnownFolderFN(REFKNOWNFOLDERID kfid, DWORD dwKFFlags, __in_opt PCWSTR pszItem, REFIID riid, __deref_out void **ppv);
145 CAutoLibrary hShell = ::LoadLibrary(_T("shell32.dll"));
146 if (hShell)
148 SHCreateItemInKnownFolderFN *pfnSHCreateItemInKnownFolder = (SHCreateItemInKnownFolderFN*)GetProcAddress(hShell, "SHCreateItemInKnownFolder");
149 if (pfnSHCreateItemInKnownFolder)
151 hr = pfnSHCreateItemInKnownFolder(FOLDERID_UsersLibraries, KF_FLAG_DEFAULT_PATH | KF_FLAG_NO_ALIAS, wszRealLibraryName, IID_PPV_ARGS(ppShellItem));
155 return hr;