bump product version to 4.1.6.2
[LibreOffice.git] / fpicker / source / win32 / filepicker / getfilenamewrapper.cxx
blob4a8eb9e8bfcaa4915156cc9d640da41c7f470a58
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdio.h>
21 #include <osl/diagnose.h>
22 #include "getfilenamewrapper.hxx"
24 #if defined _MSC_VER
25 #pragma warning(push, 1)
26 #endif
27 #include <objbase.h>
28 #include <process.h>
29 #if defined _MSC_VER
30 #pragma warning(pop)
31 #endif
33 namespace /* private */
36 //-----------------------------------------------
37 // This class prevents changing of the working
38 // directory.
39 //-----------------------------------------------
40 class CurDirGuard
42 sal_Bool m_bValid;
43 wchar_t* m_pBuffer;
44 DWORD m_nBufLen;
46 public:
47 CurDirGuard()
48 : m_bValid( sal_False )
49 , m_pBuffer( NULL )
50 , m_nBufLen( 0 )
52 m_nBufLen = GetCurrentDirectoryW( 0, NULL );
53 if ( m_nBufLen )
55 m_pBuffer = new wchar_t[m_nBufLen];
56 m_bValid = ( GetCurrentDirectoryW( m_nBufLen, m_pBuffer ) == ( m_nBufLen - 1 ) );
60 ~CurDirGuard()
62 bool bDirSet = false;
64 if ( m_pBuffer )
66 if ( m_bValid )
68 if ( m_nBufLen - 1 > MAX_PATH )
70 DWORD nNewLen = m_nBufLen + 8;
71 wchar_t* pNewBuffer = new wchar_t[nNewLen];
72 if ( m_nBufLen > 3 && m_pBuffer[0] == (wchar_t)'\\' && m_pBuffer[1] == (wchar_t)'\\' )
74 if ( m_pBuffer[2] == (wchar_t)'?' )
75 _snwprintf( pNewBuffer, nNewLen, L"%s", m_pBuffer );
76 else
77 _snwprintf( pNewBuffer, nNewLen, L"\\\\?\\UNC\\%s", m_pBuffer+2 );
79 else
80 _snwprintf( pNewBuffer, nNewLen, L"\\\\?\\%s", m_pBuffer );
81 bDirSet = SetCurrentDirectoryW( pNewBuffer );
83 delete [] pNewBuffer;
85 else
86 bDirSet = SetCurrentDirectoryW( m_pBuffer );
89 delete [] m_pBuffer;
90 m_pBuffer = NULL;
93 if ( !bDirSet )
95 // the fallback solution
96 wchar_t pPath[MAX_PATH+1];
97 if ( GetWindowsDirectoryW( pPath, MAX_PATH+1 ) <= MAX_PATH )
99 SetCurrentDirectoryW( pPath );
101 else
103 // the system path is also too long?!!
109 //-----------------------------------------------
111 //-----------------------------------------------
113 struct GetFileNameParam
115 GetFileNameParam(bool bOpen, LPOPENFILENAME lpofn) :
116 m_bOpen(bOpen),
117 m_lpofn(lpofn),
118 m_bRet(false),
119 m_ExtErr(0)
122 bool m_bOpen;
123 LPOPENFILENAME m_lpofn;
124 bool m_bRet;
125 int m_ExtErr;
128 //-----------------------------------------------
130 //-----------------------------------------------
132 unsigned __stdcall ThreadProc(void* pParam)
134 CurDirGuard aGuard;
136 GetFileNameParam* lpgfnp =
137 reinterpret_cast<GetFileNameParam*>(pParam);
139 HRESULT hr = OleInitialize( NULL );
141 if (lpgfnp->m_bOpen)
142 lpgfnp->m_bRet = GetOpenFileName(lpgfnp->m_lpofn);
143 else
144 lpgfnp->m_bRet = GetSaveFileName(lpgfnp->m_lpofn);
146 lpgfnp->m_ExtErr = CommDlgExtendedError();
148 if ( SUCCEEDED( hr ) )
149 OleUninitialize();
151 return 0;
154 //-----------------------------------------------
155 // exceutes GetOpenFileName/GetSaveFileName in
156 // a separat thread
157 //-----------------------------------------------
159 bool ThreadExecGetFileName(LPOPENFILENAME lpofn, bool bOpen, /*out*/ int& ExtErr)
161 GetFileNameParam gfnp(bOpen,lpofn);
162 unsigned id;
164 HANDLE hThread = reinterpret_cast<HANDLE>(
165 _beginthreadex(0, 0, ThreadProc, &gfnp, 0, &id));
167 OSL_POSTCOND(hThread, "could not create STA thread");
169 WaitForSingleObject(hThread, INFINITE);
170 CloseHandle(hThread);
172 ExtErr = gfnp.m_ExtErr;
174 return gfnp.m_bRet;
177 //-----------------------------------------------
178 // This function returns true if the calling
179 // thread belongs to a Multithreaded Appartment
180 // (MTA)
181 //-----------------------------------------------
183 bool IsMTA()
185 HRESULT hr = CoInitialize(NULL);
187 if (RPC_E_CHANGED_MODE == hr)
188 return true;
190 if(SUCCEEDED(hr))
191 CoUninitialize();
193 return false;
196 } // namespace private
199 //-----------------------------------------------
201 //-----------------------------------------------
203 CGetFileNameWrapper::CGetFileNameWrapper() :
204 m_ExtendedDialogError(0)
208 //-----------------------------------------------
210 //-----------------------------------------------
212 bool CGetFileNameWrapper::getOpenFileName(LPOPENFILENAME lpofn)
214 OSL_PRECOND(lpofn,"invalid parameter");
216 bool bRet = false;
218 if (IsMTA())
220 bRet = ThreadExecGetFileName(
221 lpofn, true, m_ExtendedDialogError);
223 else
225 CurDirGuard aGuard;
227 HRESULT hr = OleInitialize( NULL );
229 bRet = GetOpenFileName(lpofn);
230 m_ExtendedDialogError = CommDlgExtendedError();
232 if ( SUCCEEDED( hr ) )
233 OleUninitialize();
236 return bRet;
239 //-----------------------------------------------
241 //-----------------------------------------------
243 bool CGetFileNameWrapper::getSaveFileName(LPOPENFILENAME lpofn)
245 OSL_PRECOND(lpofn,"invalid parameter");
247 bool bRet = false;
249 if (IsMTA())
251 bRet = ThreadExecGetFileName(
252 lpofn, false, m_ExtendedDialogError);
254 else
256 CurDirGuard aGuard;
258 bRet = GetSaveFileName(lpofn);
259 m_ExtendedDialogError = CommDlgExtendedError();
262 return bRet;
265 //-----------------------------------------------
267 //-----------------------------------------------
269 int CGetFileNameWrapper::commDlgExtendedError( )
271 return m_ExtendedDialogError;
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */