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 ************************************************************************/
31 #define _WIN32_WINNT 0x0500
32 #include "systools/win32/uwinapi.h"
36 #include "file_error.h"
38 #include "path_helper.hxx"
40 #include "osl/diagnose.h"
45 //#####################################################
46 // Allocate n number of t's on the stack return a pointer to it in p
48 #define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));
50 #define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \
51 __except(EXCEPTION_EXECUTE_HANDLER) {(p) = 0;}
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;
66 oslFileError error
= osl_File_E_None
;
68 if (pustrDirectoryURL
)
69 rtl_uString_assign(&dir_url
, pustrDirectoryURL
);
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
);
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
;
106 osl_error
= osl_setup_base_directory_impl_(
107 pustrDirectoryURL
, ppustr_base_dir
);
109 *b_delete_on_close
= (sal_Bool
)(0 == ppustrTempFileURL
);
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
)),
127 osl_error
= oslTranslateFileError(GetLastError());
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
;
140 OSL_ASSERT(p_handle
);
142 if (b_delete_on_close
)
143 flags
|= FILE_FLAG_DELETE_ON_CLOSE
;
147 GENERIC_READ
| GENERIC_WRITE
,
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
,
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
))
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
);
194 //#############################################
195 oslFileError SAL_CALL
osl_createTempFile(
196 rtl_uString
* pustrDirectoryURL
,
197 oslFileHandle
* pHandle
,
198 rtl_uString
** ppustrTempFileURL
)
200 rtl_uString
* base_directory
= 0;
202 sal_Bool b_delete_on_close
;
203 oslFileError osl_error
;
205 osl_error
= osl_setup_createTempFile_impl_(
212 if (osl_File_E_None
!= 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
));
220 osl_createTempFile_impl_(
227 else // stack alloc failed
229 osl_error
= osl_File_E_NOMEM
;
233 rtl_uString_release(base_directory
);
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;
248 nLength
= GetTempPathW( aBuffer
.getBufSizeInSymbols(), lpBuffer
);
250 if ( nLength
> nBufferLength
)
252 // the provided path has invalid length
253 error
= osl_File_E_NOENT
;
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
);
269 error
= oslTranslateFileError( GetLastError() );
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */