diff options
Diffstat (limited to 'fpicker/source/win32/filepicker/getfilenamewrapper.cxx')
-rw-r--r-- | fpicker/source/win32/filepicker/getfilenamewrapper.cxx | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/fpicker/source/win32/filepicker/getfilenamewrapper.cxx b/fpicker/source/win32/filepicker/getfilenamewrapper.cxx new file mode 100644 index 000000000000..43994393e139 --- /dev/null +++ b/fpicker/source/win32/filepicker/getfilenamewrapper.cxx @@ -0,0 +1,296 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <stdio.h> +#include <osl/diagnose.h> +#include "getfilenamewrapper.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <objbase.h> +#include <process.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +namespace /* private */ +{ + + //----------------------------------------------- + // This class prevents changing of the working + // directory. + //----------------------------------------------- + class CurDirGuard + { + BOOL m_bValid; + wchar_t* m_pBuffer; + DWORD m_nBufLen; + + public: + CurDirGuard() + : m_bValid( FALSE ) + , m_pBuffer( NULL ) + , m_nBufLen( 0 ) + { + m_nBufLen = GetCurrentDirectoryW( 0, NULL ); + if ( m_nBufLen ) + { + m_pBuffer = new wchar_t[m_nBufLen]; + m_bValid = ( GetCurrentDirectoryW( m_nBufLen, m_pBuffer ) == ( m_nBufLen - 1 ) ); + } + } + + ~CurDirGuard() + { + BOOL bDirSet = FALSE; + + if ( m_pBuffer ) + { + if ( m_bValid ) + { + if ( m_nBufLen - 1 > MAX_PATH ) + { + if ( (LONG32)GetVersion() < 0 ) + { + // this is Win 98/ME branch, such a long path can not be set + // use the system path as fallback later + } + else + { + DWORD nNewLen = m_nBufLen + 8; + wchar_t* pNewBuffer = new wchar_t[nNewLen]; + if ( m_nBufLen > 3 && m_pBuffer[0] == (wchar_t)'\\' && m_pBuffer[1] == (wchar_t)'\\' ) + { + if ( m_pBuffer[2] == (wchar_t)'?' ) + _snwprintf( pNewBuffer, nNewLen, L"%s", m_pBuffer ); + else + _snwprintf( pNewBuffer, nNewLen, L"\\\\?\\UNC\\%s", m_pBuffer+2 ); + } + else + _snwprintf( pNewBuffer, nNewLen, L"\\\\?\\%s", m_pBuffer ); + bDirSet = SetCurrentDirectoryW( pNewBuffer ); + + delete [] pNewBuffer; + } + } + else + bDirSet = SetCurrentDirectoryW( m_pBuffer ); + } + + delete [] m_pBuffer; + m_pBuffer = NULL; + } + + if ( !bDirSet ) + { + // the fallback solution + wchar_t pPath[MAX_PATH+1]; + if ( GetWindowsDirectoryW( pPath, MAX_PATH+1 ) <= MAX_PATH ) + { + SetCurrentDirectoryW( pPath ); + } + else + { + // the system path is also too long?!! + } + } + } + }; + + //----------------------------------------------- + // + //----------------------------------------------- + + struct GetFileNameParam + { + GetFileNameParam(bool bOpen, LPOPENFILENAME lpofn) : + m_bOpen(bOpen), + m_lpofn(lpofn), + m_bRet(false), + m_ExtErr(0) + {} + + bool m_bOpen; + LPOPENFILENAME m_lpofn; + bool m_bRet; + int m_ExtErr; + }; + + //----------------------------------------------- + // + //----------------------------------------------- + + unsigned __stdcall ThreadProc(void* pParam) + { + CurDirGuard aGuard; + + GetFileNameParam* lpgfnp = + reinterpret_cast<GetFileNameParam*>(pParam); + + HRESULT hr = OleInitialize( NULL ); + + if (lpgfnp->m_bOpen) + lpgfnp->m_bRet = GetOpenFileName(lpgfnp->m_lpofn); + else + lpgfnp->m_bRet = GetSaveFileName(lpgfnp->m_lpofn); + + lpgfnp->m_ExtErr = CommDlgExtendedError(); + + if ( SUCCEEDED( hr ) ) + OleUninitialize(); + + return 0; + } + + //----------------------------------------------- + // exceutes GetOpenFileName/GetSaveFileName in + // a separat thread + //----------------------------------------------- + + bool ThreadExecGetFileName(LPOPENFILENAME lpofn, bool bOpen, /*out*/ int& ExtErr) + { + GetFileNameParam gfnp(bOpen,lpofn); + unsigned id; + + HANDLE hThread = reinterpret_cast<HANDLE>( + _beginthreadex(0, 0, ThreadProc, &gfnp, 0, &id)); + + OSL_POSTCOND(hThread, "could not create STA thread"); + + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + + ExtErr = gfnp.m_ExtErr; + + return gfnp.m_bRet; + } + + //----------------------------------------------- + // This function returns true if the calling + // thread belongs to a Multithreaded Appartment + // (MTA) + //----------------------------------------------- + + bool IsMTA() + { + HRESULT hr = CoInitialize(NULL); + + if (RPC_E_CHANGED_MODE == hr) + return true; + + if(SUCCEEDED(hr)) + CoUninitialize(); + + return false; + } + +} // namespace private + + +//----------------------------------------------- +// +//----------------------------------------------- + +CGetFileNameWrapper::CGetFileNameWrapper() : + m_ExtendedDialogError(0) +{ +} + +//----------------------------------------------- +// +//----------------------------------------------- + +bool CGetFileNameWrapper::getOpenFileName(LPOPENFILENAME lpofn) +{ + OSL_PRECOND(lpofn,"invalid parameter"); + + bool bRet = false; + + if (IsMTA()) + { + bRet = ThreadExecGetFileName( + lpofn, true, m_ExtendedDialogError); + } + else + { + CurDirGuard aGuard; + + HRESULT hr = OleInitialize( NULL ); + + bRet = GetOpenFileName(lpofn); + m_ExtendedDialogError = CommDlgExtendedError(); + + if ( SUCCEEDED( hr ) ) + OleUninitialize(); + } + + return bRet; +} + +//----------------------------------------------- +// +//----------------------------------------------- + +bool CGetFileNameWrapper::getSaveFileName(LPOPENFILENAME lpofn) +{ + OSL_PRECOND(lpofn,"invalid parameter"); + + bool bRet = false; + + if (IsMTA()) + { + bRet = ThreadExecGetFileName( + lpofn, false, m_ExtendedDialogError); + } + else + { + CurDirGuard aGuard; + + bRet = GetSaveFileName(lpofn); + m_ExtendedDialogError = CommDlgExtendedError(); + } + + return bRet; +} + +//----------------------------------------------- +// +//----------------------------------------------- + +int CGetFileNameWrapper::commDlgExtendedError( ) +{ + return m_ExtendedDialogError; +} + |