update dev300-m58
[ooovba.git] / sal / osl / w32 / tempfile.cxx
blob708dbe15c751f70b0244bc9e4ec8398ee63e6844
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
10 * $Revision: 1.0 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #define UNICODE
32 #define _UNICODE
33 #define _WIN32_WINNT_0x0500
34 #include "systools/win32/uwinapi.h"
36 #include "osl/file.h"
38 #include "file_error.h"
39 #include "file_url.h"
41 #include "osl/diagnose.h"
43 #include <malloc.h>
44 #include <tchar.h>
46 //#####################################################
47 #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
49 // Allocate n number of t's on the stack return a pointer to it in p
50 #ifdef __MINGW32__
51 #define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));
52 #else
53 #define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \
54 __except(EXCEPTION_EXECUTE_HANDLER) {(p) = 0;}
55 #endif
57 extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle(HANDLE hFile, sal_uInt32 uFlags);
59 //#####################################################
60 // Temp file functions
61 //#####################################################
63 static oslFileError osl_setup_base_directory_impl_(
64 rtl_uString* pustrDirectoryURL,
65 rtl_uString** ppustr_base_dir)
67 rtl_uString* dir_url = 0;
68 rtl_uString* dir = 0;
69 oslFileError error = osl_File_E_None;
71 if (pustrDirectoryURL)
72 rtl_uString_assign(&dir_url, pustrDirectoryURL);
73 else
74 error = osl_getTempDirURL(&dir_url);
76 if (osl_File_E_None == error)
78 error = _osl_getSystemPathFromFileURL(dir_url, &dir, sal_False);
79 rtl_uString_release(dir_url);
82 if (osl_File_E_None == error )
84 rtl_uString_assign(ppustr_base_dir, dir);
85 rtl_uString_release(dir);
88 return error;
91 //#####################################################
92 static oslFileError osl_setup_createTempFile_impl_(
93 rtl_uString* pustrDirectoryURL,
94 oslFileHandle* pHandle,
95 rtl_uString** ppustrTempFileURL,
96 rtl_uString** ppustr_base_dir,
97 sal_Bool* b_delete_on_close)
99 oslFileError osl_error;
101 OSL_PRECOND(((0 != pHandle) || (0 != ppustrTempFileURL)), "Invalid parameter!");
103 if ((0 == pHandle) && (0 == ppustrTempFileURL))
105 osl_error = osl_File_E_INVAL;
107 else
109 osl_error = osl_setup_base_directory_impl_(
110 pustrDirectoryURL, ppustr_base_dir);
112 *b_delete_on_close = (sal_Bool)(0 == ppustrTempFileURL);
115 return osl_error;
118 //#####################################################
119 static oslFileError osl_win32_GetTempFileName_impl_(
120 rtl_uString* base_directory, LPWSTR temp_file_name)
122 oslFileError osl_error = osl_File_E_None;
124 if (0 == GetTempFileNameW(
125 reinterpret_cast<LPCWSTR>(rtl_uString_getStr(base_directory)),
126 L"",
128 temp_file_name))
130 osl_error = oslTranslateFileError(GetLastError());
133 return osl_error;
136 //#####################################################
137 static sal_Bool osl_win32_CreateFile_impl_(
138 LPCWSTR file_name, sal_Bool b_delete_on_close, oslFileHandle* p_handle)
140 DWORD flags = FILE_ATTRIBUTE_NORMAL;
141 HANDLE hFile;
143 OSL_ASSERT(p_handle);
145 if (b_delete_on_close)
146 flags |= FILE_FLAG_DELETE_ON_CLOSE;
148 hFile = CreateFileW(
149 file_name,
150 GENERIC_READ | GENERIC_WRITE,
152 NULL,
153 TRUNCATE_EXISTING,
154 flags,
155 NULL);
157 // @@@ ERROR HANDLING @@@
158 if (IsValidHandle(hFile))
159 *p_handle = osl_createFileHandleFromOSHandle(hFile, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write);
161 return (sal_Bool)IsValidHandle(hFile);
164 //#############################################
165 static oslFileError osl_createTempFile_impl_(
166 rtl_uString* base_directory,
167 LPWSTR tmp_name,
168 sal_Bool b_delete_on_close,
169 oslFileHandle* pHandle,
170 rtl_uString** ppustrTempFileURL)
172 oslFileError osl_error;
176 osl_error = osl_win32_GetTempFileName_impl_(base_directory, tmp_name);
178 /* if file could not be opened try again */
180 if ((osl_File_E_None != osl_error) || (0 == pHandle) ||
181 osl_win32_CreateFile_impl_(tmp_name, b_delete_on_close, pHandle))
182 break;
184 } while(1); // try until success
186 if ((osl_File_E_None == osl_error) && !b_delete_on_close)
188 rtl_uString* pustr = 0;
189 rtl_uString_newFromStr(&pustr, reinterpret_cast<const sal_Unicode*>(tmp_name));
190 osl_getFileURLFromSystemPath(pustr, ppustrTempFileURL);
191 rtl_uString_release(pustr);
194 return osl_error;
197 //#############################################
198 oslFileError SAL_CALL osl_createTempFile(
199 rtl_uString* pustrDirectoryURL,
200 oslFileHandle* pHandle,
201 rtl_uString** ppustrTempFileURL)
203 rtl_uString* base_directory = 0;
204 LPWSTR tmp_name;
205 sal_Bool b_delete_on_close;
206 oslFileError osl_error;
208 osl_error = osl_setup_createTempFile_impl_(
209 pustrDirectoryURL,
210 pHandle,
211 ppustrTempFileURL,
212 &base_directory,
213 &b_delete_on_close);
215 if (osl_File_E_None != osl_error)
216 return osl_error;
218 /* allocate enough space on the stack */
219 STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH));
221 if (tmp_name)
223 osl_createTempFile_impl_(
224 base_directory,
225 tmp_name,
226 b_delete_on_close,
227 pHandle,
228 ppustrTempFileURL);
230 else // stack alloc failed
232 osl_error = osl_File_E_NOMEM;
235 if (base_directory)
236 rtl_uString_release(base_directory);
238 return osl_error;
241 //#############################################
242 oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir)
244 WCHAR szBuffer[MAX_PATH];
245 LPWSTR lpBuffer = szBuffer;
246 DWORD nBufferLength = ELEMENTS_OF_ARRAY(szBuffer) - 1;
248 DWORD nLength;
249 oslFileError error;
253 nLength = GetTempPathW( ELEMENTS_OF_ARRAY(szBuffer), lpBuffer );
254 if ( nLength > nBufferLength )
256 nLength++;
257 lpBuffer = reinterpret_cast<WCHAR*>(alloca( sizeof(WCHAR) * nLength ));
258 nBufferLength = nLength - 1;
260 } while ( nLength > nBufferLength );
262 if ( nLength )
264 rtl_uString *ustrTempPath = NULL;
266 if ( '\\' == lpBuffer[nLength-1] )
267 lpBuffer[nLength-1] = 0;
269 rtl_uString_newFromStr( &ustrTempPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) );
271 error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir );
273 rtl_uString_release( ustrTempPath );
275 else
276 error = oslTranslateFileError( GetLastError() );
278 return error;