1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008 - 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.
20 #include "BugTraqAssociations.h"
24 // {3494FA92-B139-4730-9591-01135D5E7831}
25 DEFINE_GUID(CATID_BugTraqProvider
,
26 0x3494fa92, 0xb139, 0x4730, 0x95, 0x91, 0x1, 0x13, 0x5d, 0x5e, 0x78, 0x31);
28 #define BUGTRAQ_ASSOCIATIONS_REGPATH _T("Software\\TortoiseGit\\BugTraq Associations")
30 CBugTraqAssociations::~CBugTraqAssociations()
32 for (inner_t::iterator it
= m_inner
.begin(); it
!= m_inner
.end(); ++it
)
36 void CBugTraqAssociations::Load()
39 if (RegOpenKeyEx(HKEY_CURRENT_USER
, BUGTRAQ_ASSOCIATIONS_REGPATH
, 0, KEY_READ
, &hk
) != ERROR_SUCCESS
)
42 for (DWORD dwIndex
= 0; /* nothing */; ++dwIndex
)
44 TCHAR szSubKey
[MAX_PATH
];
45 DWORD cchSubKey
= MAX_PATH
;
46 LSTATUS status
= RegEnumKeyEx(hk
, dwIndex
, szSubKey
, &cchSubKey
, NULL
, NULL
, NULL
, NULL
);
47 if (status
!= ERROR_SUCCESS
)
51 if (RegOpenKeyEx(hk
, szSubKey
, 0, KEY_READ
, &hk2
) == ERROR_SUCCESS
)
53 TCHAR szWorkingCopy
[MAX_PATH
];
54 DWORD cbWorkingCopy
= sizeof(szWorkingCopy
);
55 RegQueryValueEx(hk2
, _T("WorkingCopy"), NULL
, NULL
, (LPBYTE
)szWorkingCopy
, &cbWorkingCopy
);
57 TCHAR szClsid
[MAX_PATH
];
58 DWORD cbClsid
= sizeof(szClsid
);
59 RegQueryValueEx(hk2
, _T("Provider"), NULL
, NULL
, (LPBYTE
)szClsid
, &cbClsid
);
62 CLSIDFromString(szClsid
, &provider_clsid
);
64 DWORD cbParameters
= 0;
65 RegQueryValueEx(hk2
, _T("Parameters"), NULL
, NULL
, (LPBYTE
)NULL
, &cbParameters
);
66 TCHAR
* szParameters
= new TCHAR
[cbParameters
+1];
67 RegQueryValueEx(hk2
, _T("Parameters"), NULL
, NULL
, (LPBYTE
)szParameters
, &cbParameters
);
68 szParameters
[cbParameters
] = 0;
69 m_inner
.push_back(new CBugTraqAssociation(szWorkingCopy
, provider_clsid
, LookupProviderName(provider_clsid
), szParameters
));
70 delete [] szParameters
;
79 void CBugTraqAssociations::Add(const CBugTraqAssociation
&assoc
)
81 m_inner
.push_back(new CBugTraqAssociation(assoc
));
84 bool CBugTraqAssociations::FindProvider(const CTGitPathList
&pathList
, CBugTraqAssociation
*assoc
) const
86 return FindProviderForPathList(pathList
, assoc
);
89 bool CBugTraqAssociations::FindProvider(const CString
&path
, CBugTraqAssociation
*assoc
) const
93 gitpath
.SetFromUnknown(path
);
94 return FindProviderForPath(gitpath
,assoc
);
97 bool CBugTraqAssociations::FindProviderForPathList(const CTGitPathList
&pathList
, CBugTraqAssociation
*assoc
) const
99 for (int i
= 0; i
< pathList
.GetCount(); ++i
)
101 CTGitPath path
= pathList
[i
];
102 if (FindProviderForPath(path
, assoc
))
109 bool CBugTraqAssociations::FindProviderForPath(CTGitPath path
, CBugTraqAssociation
*assoc
) const
113 inner_t::const_iterator it
= std::find_if(m_inner
.begin(), m_inner
.end(), FindByPathPred(path
));
114 if (it
!= m_inner
.end())
120 path
= path
.GetContainingDirectory();
121 } while(!path
.IsEmpty());
127 CString
CBugTraqAssociations::LookupProviderName(const CLSID
&provider_clsid
)
130 StringFromGUID2(provider_clsid
, szClsid
, ARRAYSIZE(szClsid
));
132 TCHAR szSubKey
[MAX_PATH
];
133 _stprintf_s(szSubKey
, _T("CLSID\\%ls"), szClsid
);
135 CString provider_name
= CString(szClsid
);
138 if (RegOpenKeyEx(HKEY_CLASSES_ROOT
, szSubKey
, 0, KEY_READ
, &hk
) == ERROR_SUCCESS
)
140 TCHAR szClassName
[MAX_PATH
];
141 DWORD cbClassName
= sizeof(szClassName
);
143 if (RegQueryValueEx(hk
, NULL
, NULL
, NULL
, (LPBYTE
)szClassName
, &cbClassName
) == ERROR_SUCCESS
)
144 provider_name
= CString(szClassName
);
149 return provider_name
;
152 LSTATUS
RegSetValueFromCString(HKEY hKey
, LPCTSTR lpValueName
, CString str
)
155 DWORD cb
= (str
.GetLength() + 1) * sizeof(TCHAR
);
156 return RegSetValueEx(hKey
, lpValueName
, 0, REG_SZ
, (const BYTE
*)lpsz
, cb
);
159 void CBugTraqAssociations::Save() const
161 SHDeleteKey(HKEY_CURRENT_USER
, BUGTRAQ_ASSOCIATIONS_REGPATH
);
164 if (RegCreateKeyEx(HKEY_CURRENT_USER
, BUGTRAQ_ASSOCIATIONS_REGPATH
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
, &hk
, NULL
) != ERROR_SUCCESS
)
168 for (const_iterator it
= begin(); it
!= end(); ++it
)
170 TCHAR szSubKey
[MAX_PATH
];
171 _stprintf_s(szSubKey
, _T("%d"), dwIndex
);
174 if (RegCreateKeyEx(hk
, szSubKey
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hk2
, NULL
) == ERROR_SUCCESS
)
176 RegSetValueFromCString(hk2
, _T("Provider"), (*it
)->GetProviderClassAsString());
177 RegSetValueFromCString(hk2
, _T("WorkingCopy"), (*it
)->GetPath().GetWinPath());
178 RegSetValueFromCString(hk2
, _T("Parameters"), (*it
)->GetParameters());
189 void CBugTraqAssociations::RemoveByPath(const CTGitPath
&path
)
191 inner_t::iterator it
= std::find_if(m_inner
.begin(), m_inner
.end(), FindByPathPred(path
));
192 if (it
!= m_inner
.end())
199 CString
CBugTraqAssociation::GetProviderClassAsString() const
202 StringFromGUID2(m_provider
.clsid
, szTemp
, ARRAYSIZE(szTemp
));
204 return CString(szTemp
);
208 std::vector
<CBugTraqProvider
> CBugTraqAssociations::GetAvailableProviders()
210 std::vector
<CBugTraqProvider
> results
;
212 ICatInformation
*pCatInformation
= NULL
;
215 if (SUCCEEDED(hr
= CoCreateInstance(CLSID_StdComponentCategoriesMgr
, NULL
, CLSCTX_ALL
, IID_ICatInformation
, (void **)&pCatInformation
)))
217 IEnumGUID
*pEnum
= NULL
;
218 if (SUCCEEDED(hr
= pCatInformation
->EnumClassesOfCategories(1, &CATID_BugTraqProvider
, 0, NULL
, &pEnum
)))
226 hrEnum
= pEnum
->Next(ARRAYSIZE(clsids
), clsids
, &cClsids
);
227 if (SUCCEEDED(hrEnum
))
229 for (ULONG i
= 0; i
< cClsids
; ++i
)
231 CBugTraqProvider provider
;
232 provider
.clsid
= clsids
[i
];
233 provider
.name
= LookupProviderName(clsids
[i
]);
234 results
.push_back(provider
);
237 } while (hrEnum
== S_OK
);
246 pCatInformation
->Release();
247 pCatInformation
= NULL
;