OSDN Git Service

Fixed issue #187: Allow start new rebase after finish rebase
[tortoisegit/TortoiseGitJp.git] / src / Utils / BugTraqAssociations.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "stdafx.h"\r
20 #include "BugTraqAssociations.h"\r
21 \r
22 #include <initguid.h>\r
23 \r
24 // {3494FA92-B139-4730-9591-01135D5E7831}\r
25 DEFINE_GUID(CATID_BugTraqProvider, \r
26                         0x3494fa92, 0xb139, 0x4730, 0x95, 0x91, 0x1, 0x13, 0x5d, 0x5e, 0x78, 0x31);\r
27 \r
28 #define BUGTRAQ_ASSOCIATIONS_REGPATH _T("Software\\TortoiseGit\\BugTraq Associations")\r
29 \r
30 CBugTraqAssociations::~CBugTraqAssociations()\r
31 {\r
32         for (inner_t::iterator it = m_inner.begin(); it != m_inner.end(); ++it)\r
33                 delete *it;\r
34 }\r
35 \r
36 void CBugTraqAssociations::Load()\r
37 {\r
38         HKEY hk;\r
39         if (RegOpenKeyEx(HKEY_CURRENT_USER, BUGTRAQ_ASSOCIATIONS_REGPATH, 0, KEY_READ, &hk) != ERROR_SUCCESS)\r
40                 return;\r
41 \r
42         for (DWORD dwIndex = 0; /* nothing */; ++dwIndex)\r
43         {\r
44                 TCHAR szSubKey[MAX_PATH];\r
45                 DWORD cchSubKey = MAX_PATH;\r
46                 LSTATUS status = RegEnumKeyEx(hk, dwIndex, szSubKey, &cchSubKey, NULL, NULL, NULL, NULL);\r
47                 if (status != ERROR_SUCCESS)\r
48                         break;\r
49 \r
50                 HKEY hk2;\r
51                 if (RegOpenKeyEx(hk, szSubKey, 0, KEY_READ, &hk2) == ERROR_SUCCESS)\r
52                 {\r
53                         TCHAR szWorkingCopy[MAX_PATH];\r
54                         DWORD cbWorkingCopy = sizeof(szWorkingCopy);\r
55                         RegQueryValueEx(hk2, _T("WorkingCopy"), NULL, NULL, (LPBYTE)szWorkingCopy, &cbWorkingCopy);\r
56 \r
57                         TCHAR szClsid[MAX_PATH];\r
58                         DWORD cbClsid = sizeof(szClsid);\r
59                         RegQueryValueEx(hk2, _T("Provider"), NULL, NULL, (LPBYTE)szClsid, &cbClsid);\r
60 \r
61                         CLSID provider_clsid;\r
62                         CLSIDFromString(szClsid, &provider_clsid);\r
63 \r
64                         DWORD cbParameters = 0;\r
65                         RegQueryValueEx(hk2, _T("Parameters"), NULL, NULL, (LPBYTE)NULL, &cbParameters);\r
66                         TCHAR * szParameters = new TCHAR[cbParameters+1];\r
67                         RegQueryValueEx(hk2, _T("Parameters"), NULL, NULL, (LPBYTE)szParameters, &cbParameters);\r
68                         szParameters[cbParameters] = 0;\r
69                         m_inner.push_back(new CBugTraqAssociation(szWorkingCopy, provider_clsid, LookupProviderName(provider_clsid), szParameters));\r
70                         delete [] szParameters;\r
71 \r
72                         RegCloseKey(hk2);\r
73                 }\r
74         }\r
75 \r
76         RegCloseKey(hk);\r
77 }\r
78 \r
79 void CBugTraqAssociations::Add(const CBugTraqAssociation &assoc)\r
80 {\r
81         m_inner.push_back(new CBugTraqAssociation(assoc));\r
82 }\r
83 \r
84 bool CBugTraqAssociations::FindProvider(const CTGitPathList &pathList, CBugTraqAssociation *assoc) const\r
85 {\r
86         return FindProviderForPathList(pathList, assoc);\r
87 }\r
88 \r
89 bool CBugTraqAssociations::FindProvider(const CString &path, CBugTraqAssociation *assoc) const\r
90 {\r
91 \r
92         CTGitPath gitpath;\r
93         gitpath.SetFromUnknown(path);\r
94         return FindProviderForPath(gitpath,assoc);\r
95 \r
96 }\r
97 bool CBugTraqAssociations::FindProviderForPathList(const CTGitPathList &pathList, CBugTraqAssociation *assoc) const\r
98 {\r
99         for (int i = 0; i < pathList.GetCount(); ++i)\r
100         {\r
101                 CTGitPath path = pathList[i];\r
102                 if (FindProviderForPath(path, assoc))\r
103                         return true;\r
104         }\r
105 \r
106         return false;\r
107 }\r
108 \r
109 bool CBugTraqAssociations::FindProviderForPath(CTGitPath path, CBugTraqAssociation *assoc) const\r
110 {\r
111         do\r
112         {\r
113                 inner_t::const_iterator it = std::find_if(m_inner.begin(), m_inner.end(), FindByPathPred(path));\r
114                 if (it != m_inner.end())\r
115                 {\r
116                         *assoc = *(*it);\r
117                         return true;\r
118                 }\r
119                 \r
120                 path = path.GetContainingDirectory();\r
121         } while(!path.IsEmpty());\r
122 \r
123         return false;\r
124 }\r
125 \r
126 /* static */\r
127 CString CBugTraqAssociations::LookupProviderName(const CLSID &provider_clsid)\r
128 {\r
129         OLECHAR szClsid[40];\r
130         StringFromGUID2(provider_clsid, szClsid, ARRAYSIZE(szClsid));\r
131 \r
132         TCHAR szSubKey[MAX_PATH];\r
133         _stprintf_s(szSubKey, _T("CLSID\\%ls"), szClsid);\r
134         \r
135         CString provider_name = CString(szClsid);\r
136 \r
137         HKEY hk;\r
138         if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szSubKey, 0, KEY_READ, &hk) == ERROR_SUCCESS)\r
139         {\r
140                 TCHAR szClassName[MAX_PATH];\r
141                 DWORD cbClassName = sizeof(szClassName);\r
142 \r
143                 if (RegQueryValueEx(hk, NULL, NULL, NULL, (LPBYTE)szClassName, &cbClassName) == ERROR_SUCCESS)\r
144                         provider_name = CString(szClassName);\r
145 \r
146                 RegCloseKey(hk);\r
147         }\r
148 \r
149         return provider_name;\r
150 }\r
151 \r
152 LSTATUS RegSetValueFromCString(HKEY hKey, LPCTSTR lpValueName, CString str)\r
153 {\r
154         LPCTSTR lpsz = str;\r
155         DWORD cb = (str.GetLength() + 1) * sizeof(TCHAR);\r
156         return RegSetValueEx(hKey, lpValueName, 0, REG_SZ, (const BYTE *)lpsz, cb);\r
157 }\r
158 \r
159 void CBugTraqAssociations::Save() const\r
160 {\r
161         SHDeleteKey(HKEY_CURRENT_USER, BUGTRAQ_ASSOCIATIONS_REGPATH);\r
162 \r
163         HKEY hk;\r
164         if (RegCreateKeyEx(HKEY_CURRENT_USER, BUGTRAQ_ASSOCIATIONS_REGPATH, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hk, NULL) != ERROR_SUCCESS)\r
165                 return;\r
166 \r
167         DWORD dwIndex = 0;\r
168         for (const_iterator it = begin(); it != end(); ++it)\r
169         {\r
170                 TCHAR szSubKey[MAX_PATH];\r
171                 _stprintf_s(szSubKey, _T("%d"), dwIndex);\r
172 \r
173                 HKEY hk2;\r
174                 if (RegCreateKeyEx(hk, szSubKey, 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL) == ERROR_SUCCESS)\r
175                 {\r
176                         RegSetValueFromCString(hk2, _T("Provider"), (*it)->GetProviderClassAsString());\r
177                         RegSetValueFromCString(hk2, _T("WorkingCopy"), (*it)->GetPath().GetWinPath());\r
178                         RegSetValueFromCString(hk2, _T("Parameters"), (*it)->GetParameters());\r
179                         \r
180                         RegCloseKey(hk2);\r
181                 }\r
182 \r
183                 ++dwIndex;\r
184         }\r
185 \r
186         RegCloseKey(hk);\r
187 }\r
188 \r
189 void CBugTraqAssociations::RemoveByPath(const CTGitPath &path)\r
190 {\r
191         inner_t::iterator it = std::find_if(m_inner.begin(), m_inner.end(), FindByPathPred(path));\r
192         if (it != m_inner.end())\r
193         {\r
194                 delete *it;\r
195                 m_inner.erase(it);\r
196         }\r
197 }\r
198 \r
199 CString CBugTraqAssociation::GetProviderClassAsString() const\r
200 {\r
201         OLECHAR szTemp[40];\r
202         StringFromGUID2(m_provider.clsid, szTemp, ARRAYSIZE(szTemp));\r
203 \r
204         return CString(szTemp);\r
205 }\r
206 \r
207 /* static */\r
208 std::vector<CBugTraqProvider> CBugTraqAssociations::GetAvailableProviders()\r
209 {\r
210         std::vector<CBugTraqProvider> results;\r
211 \r
212         ICatInformation *pCatInformation = NULL;\r
213 \r
214         HRESULT hr;\r
215         if (SUCCEEDED(hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatInformation, (void **)&pCatInformation)))\r
216         {\r
217                 IEnumGUID *pEnum = NULL;\r
218                 if (SUCCEEDED(hr = pCatInformation->EnumClassesOfCategories(1, &CATID_BugTraqProvider, 0, NULL, &pEnum)))\r
219                 {\r
220                         HRESULT hrEnum;\r
221                         do\r
222                         {\r
223                                 CLSID clsids[5];\r
224                                 ULONG cClsids;\r
225 \r
226                                 hrEnum = pEnum->Next(ARRAYSIZE(clsids), clsids, &cClsids);\r
227                                 if (SUCCEEDED(hrEnum))\r
228                                 {\r
229                                         for (ULONG i = 0; i < cClsids; ++i)\r
230                                         {\r
231                                                 CBugTraqProvider provider;\r
232                                                 provider.clsid = clsids[i];\r
233                                                 provider.name = LookupProviderName(clsids[i]);\r
234                                                 results.push_back(provider);\r
235                                         }\r
236                                 }\r
237                         } while (hrEnum == S_OK);\r
238                 }\r
239 \r
240                 if (pEnum)\r
241                         pEnum->Release();\r
242                 pEnum = NULL;\r
243         }\r
244 \r
245         if (pCatInformation)\r
246                 pCatInformation->Release();\r
247         pCatInformation = NULL;\r
248 \r
249         return results;\r
250 }\r