Index: TortoiseProc/BstrSafeVector.h
===================================================================
--- TortoiseProc/BstrSafeVector.h	(revision 0)
+++ TortoiseProc/BstrSafeVector.h	(revision 0)
@@ -0,0 +1,46 @@
+#pragma once
+
+class CBstrSafeVector {
+public:
+	CBstrSafeVector() : controlled( 0 ) {}
+	CBstrSafeVector( ULONG count );
+	~CBstrSafeVector() { release(); }
+	
+	operator SAFEARRAY*() { return controlled; }
+	operator const SAFEARRAY*() const { return controlled; }
+
+	SAFEARRAY** operator&();
+
+	HRESULT PutElement( LONG index, const CString& value );
+
+private:
+	SAFEARRAY* controlled;
+
+	void release();
+};
+
+inline CBstrSafeVector::CBstrSafeVector( ULONG count )
+{
+	controlled = SafeArrayCreateVector(VT_BSTR, 0, count);
+}
+
+inline SAFEARRAY** CBstrSafeVector::operator&()
+{
+	release();
+	return &controlled;
+}
+
+inline HRESULT CBstrSafeVector::PutElement( LONG index, const CString& value )
+{
+	ATL::CComBSTR valueBstr;
+	valueBstr.Attach( value.AllocSysString() );
+	return SafeArrayPutElement(controlled, &index, valueBstr);
+}
+
+inline void CBstrSafeVector::release()
+{
+	if(controlled == 0)
+		return;
+	SafeArrayDestroy(controlled);
+	controlled = 0;
+}

Property changes on: TortoiseProc\BstrSafeVector.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: TortoiseProc/CommitDlg.cpp
===================================================================
--- TortoiseProc/CommitDlg.cpp	(revision 18308)
+++ TortoiseProc/CommitDlg.cpp	(working copy)
@@ -34,6 +34,7 @@
 #include "auto_buffer.h"
 #include "COMError.h"
 #include "..\version.h"
+#include "BstrSafeVector.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -615,22 +616,15 @@
 			ATL::CComBSTR commonRoot(m_pathList.GetCommonRoot().GetDirectory().GetWinPath());
 			ATL::CComBSTR commitMessage;
 			commitMessage.Attach(m_sLogMessage.AllocSysString());
-			SAFEARRAY *pathList = SafeArrayCreateVector(VT_BSTR, 0, m_selectedPathList.GetCount());
+			CBstrSafeVector pathList(m_selectedPathList.GetCount());
 
 			for (LONG index = 0; index < m_selectedPathList.GetCount(); ++index)
-			{
-				ATL::CComBSTR path;
-				path.Attach(m_selectedPathList[index].GetSVNPathString().AllocSysString());
-				SafeArrayPutElement(pathList, &index, path);
-			}
+				pathList.PutElement(index, m_selectedPathList[index].GetSVNPathString());
 			
 			hr = pProvider2->CheckCommit(GetSafeHwnd(), parameters, repositoryRoot, commonRoot, pathList, commitMessage, &temp);
 			if (FAILED(hr))
 			{
-				COMError ce(hr);
-				CString sErr;
-				sErr.FormatMessage(IDS_ERR_FAILEDISSUETRACKERCOM, m_bugtraq_association.GetProviderName(), ce.GetMessageAndDescription().c_str());
-				CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);
+				OnComError(hr);
 			}
 			else
 			{
@@ -1356,14 +1350,10 @@
 	ATL::CComBSTR parameters;
 	parameters.Attach(m_bugtraq_association.GetParameters().AllocSysString());
 	ATL::CComBSTR commonRoot(m_pathList.GetCommonRoot().GetDirectory().GetWinPath());
-	SAFEARRAY *pathList = SafeArrayCreateVector(VT_BSTR, 0, m_pathList.GetCount());
+	CBstrSafeVector pathList(m_pathList.GetCount());
 
 	for (LONG index = 0; index < m_pathList.GetCount(); ++index)
-	{
-		ATL::CComBSTR path;
-		path.Attach(m_pathList[index].GetSVNPathString().AllocSysString());
-		SafeArrayPutElement(pathList, &index, path);
-	}
+		pathList.PutElement(index, m_pathList[index].GetSVNPathString());
 
 	ATL::CComBSTR originalMessage;
 	originalMessage.Attach(sMsg.AllocSysString());
@@ -1382,14 +1372,11 @@
 		GetDlgItemText(IDC_BUGID, m_sBugID);
 		ATL::CComBSTR bugID;
 		bugID.Attach(m_sBugID.AllocSysString());
-		SAFEARRAY * revPropNames = NULL;
-		SAFEARRAY * revPropValues = NULL;
+		CBstrSafeVector revPropNames;
+		CBstrSafeVector revPropValues;
 		if (FAILED(hr = pProvider2->GetCommitMessage2(GetSafeHwnd(), parameters, repositoryRoot, commonRoot, pathList, originalMessage, bugID, &bugIDOut, &revPropNames, &revPropValues, &temp)))
 		{
-			COMError ce(hr);
-			CString sErr;
-			sErr.FormatMessage(IDS_ERR_FAILEDISSUETRACKERCOM, m_bugtraq_association.GetProviderName(), ce.GetMessageAndDescription().c_str());
-			CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);
+			OnComError(hr);
 		}
 		else
 		{
@@ -1419,10 +1406,6 @@
 				}
 				SafeArrayUnaccessData(revPropNames);
 			}
-			if (revPropNames)
-				SafeArrayDestroy(revPropNames);
-			if (revPropValues)
-				SafeArrayDestroy(revPropValues);
 		}
 	}
 	else
@@ -1432,19 +1415,13 @@
 		hr = m_BugTraqProvider.QueryInterface(&pProvider);
 		if (FAILED(hr))
 		{
-			COMError ce(hr);
-			CString sErr;
-			sErr.FormatMessage(IDS_ERR_FAILEDISSUETRACKERCOM, m_bugtraq_association.GetProviderName(), ce.GetMessageAndDescription().c_str());
-			CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);
+			OnComError(hr);
 			return;
 		}
 
 		if (FAILED(hr = pProvider->GetCommitMessage(GetSafeHwnd(), parameters, commonRoot, pathList, originalMessage, &temp)))
 		{
-			COMError ce(hr);
-			CString sErr;
-			sErr.FormatMessage(IDS_ERR_FAILEDISSUETRACKERCOM, m_bugtraq_association.GetProviderName(), ce.GetMessageAndDescription().c_str());
-			CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);
+			OnComError(hr);
 		}
 		else
 			m_cLogMessage.SetText((LPCTSTR)temp);
@@ -1460,8 +1437,6 @@
 	}
 
 	m_cLogMessage.SetFocus();
-
-	SafeArrayDestroy(pathList);
 }
 
 LRESULT CCommitDlg::OnSVNStatusListCtrlCheckChanged(WPARAM, LPARAM)
@@ -1512,6 +1487,13 @@
 	DialogEnableWindow(IDOK, bValidLogSize && nSelectedItems>0);
 }
 
+void CCommitDlg::OnComError( HRESULT hr )
+{
+	COMError ce(hr);
+	CString sErr;
+	sErr.FormatMessage(IDS_ERR_FAILEDISSUETRACKERCOM, m_bugtraq_association.GetProviderName(), ce.GetMessageAndDescription().c_str());
+	CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);
+}
 
 LRESULT CCommitDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
 {
@@ -1610,7 +1592,6 @@
     SetSplitterRange();
 }
 
-
 void CCommitDlg::OnBnClickedShowexternals()
 {
 	m_tooltips.Pop();	// hide the tooltips
@@ -1690,4 +1671,4 @@
 
 		m_cUpdateLink.ShowWindow(SW_SHOW);
 	}
-}
\ No newline at end of file
+}
Index: TortoiseProc/CommitDlg.h
===================================================================
--- TortoiseProc/CommitDlg.h	(revision 18308)
+++ TortoiseProc/CommitDlg.h	(working copy)
@@ -61,6 +61,7 @@
 	static UINT StatusThreadEntry(LPVOID pVoid);
 	UINT StatusThread();
 	void UpdateOKButton();
+	void OnComError( HRESULT hr );
 
 // Dialog Data
 	enum { IDD = IDD_COMMITDLG };
Index: TortoiseProc/SVNProgressDlg.cpp
===================================================================
--- TortoiseProc/SVNProgressDlg.cpp	(revision 18308)
+++ TortoiseProc/SVNProgressDlg.cpp	(working copy)
@@ -44,6 +44,7 @@
 #include "SVNProperties.h"
 #include "COMError.h"
 #include "CmdLineParser.h"
+#include "BstrSafeVector.h"
 
 BOOL	CSVNProgressDlg::m_bAscending = FALSE;
 int		CSVNProgressDlg::m_nSortedColumn = -1;
@@ -2182,14 +2183,10 @@
 			if (SUCCEEDED(hr))
 			{
 				ATL::CComBSTR commonRoot(m_selectedPaths.GetCommonRoot().GetDirectory().GetWinPath());
-				SAFEARRAY *pathList = SafeArrayCreateVector(VT_BSTR, 0, m_selectedPaths.GetCount());
+				CBstrSafeVector pathList(m_selectedPaths.GetCount());
 
 				for (LONG index = 0; index < m_selectedPaths.GetCount(); ++index)
-				{
-					ATL::CComBSTR path;
-					path.Attach(m_selectedPaths[index].GetSVNPathString().AllocSysString());
-					SafeArrayPutElement(pathList, &index, path);
-				}
+					pathList.PutElement(index, m_selectedPaths[index].GetSVNPathString());
 
 				ATL::CComBSTR logMessage;
 				logMessage.Attach(m_sMessage.AllocSysString());
Index: TortoiseProc/TortoiseProc.vcproj
===================================================================
--- TortoiseProc/TortoiseProc.vcproj	(revision 18308)
+++ TortoiseProc/TortoiseProc.vcproj	(working copy)
@@ -2199,6 +2199,10 @@
 					>
 				</File>
 				<File
+					RelativePath=".\BstrSafeVector.h"
+					>
+				</File>
+				<File
 					RelativePath=".\Commands\CatCommand.cpp"
 					>
 				</File>
Index: Utils/PathUtils.cpp
===================================================================
--- Utils/PathUtils.cpp	(revision 18308)
+++ Utils/PathUtils.cpp	(working copy)
@@ -385,7 +385,6 @@
 	return CString (path) + _T('\\');
 }
 
-
 CStringA CPathUtils::PathUnescape(const CStringA& path)
 {
 	auto_buffer<char> urlabuf (path.GetLength()+1);
@@ -398,12 +397,11 @@
 
 CStringW CPathUtils::PathUnescape(const CStringW& path)
 {
-	char * buf;
-	CStringA patha;
 	int len = path.GetLength();
 	if (len==0)
 		return CStringW();
-	buf = patha.GetBuffer(len*4 + 1);
+	CStringA patha;
+	char * buf = patha.GetBuffer(len*4 + 1);
 	int lengthIncTerminator = WideCharToMultiByte(CP_UTF8, 0, path, -1, buf, len*4, NULL, NULL);
 	patha.ReleaseBuffer(lengthIncTerminator-1);
 
@@ -420,13 +418,11 @@
 CString CPathUtils::PathUnescape (const char* path)
 {
 	// try quick path
-
 	size_t i = 0;
 	for (; char c = path[i]; ++i)
 		if ((c >= 0x80) || (c == '%'))
 		{
 			// quick path does not work for non-latin or escaped chars
-
 			std::string utf8Path (path);
 
 			CPathUtils::Unescape (&utf8Path[0]);
@@ -434,7 +430,6 @@
 		}
 
 	// no escapement necessary, just unicode conversion
-
 	CString result;
 	CUnicodeUtils::UTF8ToUTF16 (path, i+1, result.GetBufferSetLength (i+1));
 	result.ReleaseBuffer();
