Bump for 3.6-28
[LibreOffice.git] / sal / osl / w32 / tempfile.cxx
blob9922b699a932604d2f76ee9866ac6646800425e4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #define UNICODE
30 #define _UNICODE
31 #define _WIN32_WINNT 0x0500
32 #include "systools/win32/uwinapi.h"
34 #include "osl/file.h"
36 #include "file_error.h"
37 #include "file_url.h"
38 #include "path_helper.hxx"
40 #include "osl/diagnose.h"
42 #include <malloc.h>
43 #include <tchar.h>
45 //#####################################################
46 // Allocate n number of t's on the stack return a pointer to it in p
47 #ifdef __MINGW32__
48 #define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));
49 #else
50 #define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \
51 __except(EXCEPTION_EXECUTE_HANDLER) {(p) = 0;}
52 #endif
54 extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle(HANDLE hFile, sal_uInt32 uFlags);
56 //#####################################################
57 // Temp file functions
58 //#####################################################
60 static oslFileError osl_setup_base_directory_impl_(
61 rtl_uString* pustrDirectoryURL,
62 rtl_uString** ppustr_base_dir)
64 rtl_uString* dir_url = 0;
65 rtl_uString* dir = 0;
66 oslFileError error = osl_File_E_None;
68 if (pustrDirectoryURL)
69 rtl_uString_assign(&dir_url, pustrDirectoryURL);
70 else
71 error = osl_getTempDirURL(&dir_url);
73 if (osl_File_E_None == error)
75 error = _osl_getSystemPathFromFileURL(dir_url, &dir, sal_False);
76 rtl_uString_release(dir_url);
79 if (osl_File_E_None == error )
81 rtl_uString_assign(ppustr_base_dir, dir);
82 rtl_uString_release(dir);
85 return error;
88 //#####################################################
89 static oslFileError osl_setup_createTempFile_impl_(
90 rtl_uString* pustrDirectoryURL,
91 oslFileHandle* pHandle,
92 rtl_uString** ppustrTempFileURL,
93 rtl_uString** ppustr_base_dir,
94 sal_Bool* b_delete_on_close)
96 oslFileError osl_error;
98 OSL_PRECOND(((0 != pHandle) || (0 != ppustrTempFileURL)), "Invalid parameter!");
100 if ((0 == pHandle) && (0 == ppustrTempFileURL))
102 osl_error = osl_File_E_INVAL;
104 else
106 osl_error = osl_setup_base_directory_impl_(
107 pustrDirectoryURL, ppustr_base_dir);
109 *b_delete_on_close = (sal_Bool)(0 == ppustrTempFileURL);
112 return osl_error;
115 //#####################################################
116 static oslFileError osl_win32_GetTempFileName_impl_(
117 rtl_uString* base_directory, LPWSTR temp_file_name)
119 oslFileError osl_error = osl_File_E_None;
121 if (0 == GetTempFileNameW(
122 reinterpret_cast<LPCWSTR>(rtl_uString_getStr(base_directory)),
123 L"",
125 temp_file_name))
127 osl_error = oslTranslateFileError(GetLastError());
130 return osl_error;
133 //#####################################################
134 static sal_Bool osl_win32_CreateFile_impl_(
135 LPCWSTR file_name, sal_Bool b_delete_on_close, oslFileHandle* p_handle)
137 DWORD flags = FILE_ATTRIBUTE_NORMAL;
138 HANDLE hFile;
140 OSL_ASSERT(p_handle);
142 if (b_delete_on_close)
143 flags |= FILE_FLAG_DELETE_ON_CLOSE;
145 hFile = CreateFileW(
146 file_name,
147 GENERIC_READ | GENERIC_WRITE,
149 NULL,
150 TRUNCATE_EXISTING,
151 flags,
152 NULL);
154 // @@@ ERROR HANDLING @@@
155 if (IsValidHandle(hFile))
156 *p_handle = osl_createFileHandleFromOSHandle(hFile, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write);
158 return (sal_Bool)IsValidHandle(hFile);
161 //#############################################
162 static oslFileError osl_createTempFile_impl_(
163 rtl_uString* base_directory,
164 LPWSTR tmp_name,
165 sal_Bool b_delete_on_close,
166 oslFileHandle* pHandle,
167 rtl_uString** ppustrTempFileURL)
169 oslFileError osl_error;
173 osl_error = osl_win32_GetTempFileName_impl_(base_directory, tmp_name);
175 /* if file could not be opened try again */
177 if ((osl_File_E_None != osl_error) || (0 == pHandle) ||
178 osl_win32_CreateFile_impl_(tmp_name, b_delete_on_close, pHandle))
179 break;
181 } while(1); // try until success
183 if ((osl_File_E_None == osl_error) && !b_delete_on_close)
185 rtl_uString* pustr = 0;
186 rtl_uString_newFromStr(&pustr, reinterpret_cast<const sal_Unicode*>(tmp_name));
187 osl_getFileURLFromSystemPath(pustr, ppustrTempFileURL);
188 rtl_uString_release(pustr);
191 return osl_error;
194 //#############################################
195 oslFileError SAL_CALL osl_createTempFile(
196 rtl_uString* pustrDirectoryURL,
197 oslFileHandle* pHandle,
198 rtl_uString** ppustrTempFileURL)
200 rtl_uString* base_directory = 0;
201 LPWSTR tmp_name;
202 sal_Bool b_delete_on_close;
203 oslFileError osl_error;
205 osl_error = osl_setup_createTempFile_impl_(
206 pustrDirectoryURL,
207 pHandle,
208 ppustrTempFileURL,
209 &base_directory,
210 &b_delete_on_close);
212 if (osl_File_E_None != osl_error)
213 return osl_error;
215 /* allocate enough space on the stack, the file name can not be longer than MAX_PATH */
216 STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH));
218 if (tmp_name)
220 osl_createTempFile_impl_(
221 base_directory,
222 tmp_name,
223 b_delete_on_close,
224 pHandle,
225 ppustrTempFileURL);
227 else // stack alloc failed
229 osl_error = osl_File_E_NOMEM;
232 if (base_directory)
233 rtl_uString_release(base_directory);
235 return osl_error;
238 //#############################################
239 oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir)
241 ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
242 LPWSTR lpBuffer = ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer);
243 DWORD nBufferLength = aBuffer.getBufSizeInSymbols() - 1;
245 DWORD nLength;
246 oslFileError error;
248 nLength = GetTempPathW( aBuffer.getBufSizeInSymbols(), lpBuffer );
250 if ( nLength > nBufferLength )
252 // the provided path has invalid length
253 error = osl_File_E_NOENT;
255 else if ( nLength )
257 rtl_uString *ustrTempPath = NULL;
259 if ( '\\' == lpBuffer[nLength-1] )
260 lpBuffer[nLength-1] = 0;
262 rtl_uString_newFromStr( &ustrTempPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) );
264 error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir );
266 rtl_uString_release( ustrTempPath );
268 else
269 error = oslTranslateFileError( GetLastError() );
271 return error;
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */