1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
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 ************************************************************************/
33 #define _WIN32_WINNT_0x0500
34 #include "systools/win32/uwinapi.h"
38 #include "file_error.h"
41 #include "osl/diagnose.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
51 #define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));
53 #define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \
54 __except(EXCEPTION_EXECUTE_HANDLER) {(p) = 0;}
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;
69 oslFileError error
= osl_File_E_None
;
71 if (pustrDirectoryURL
)
72 rtl_uString_assign(&dir_url
, pustrDirectoryURL
);
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
);
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
;
109 osl_error
= osl_setup_base_directory_impl_(
110 pustrDirectoryURL
, ppustr_base_dir
);
112 *b_delete_on_close
= (sal_Bool
)(0 == ppustrTempFileURL
);
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
)),
130 osl_error
= oslTranslateFileError(GetLastError());
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
;
143 OSL_ASSERT(p_handle
);
145 if (b_delete_on_close
)
146 flags
|= FILE_FLAG_DELETE_ON_CLOSE
;
150 GENERIC_READ
| GENERIC_WRITE
,
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
,
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
))
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
);
197 //#############################################
198 oslFileError SAL_CALL
osl_createTempFile(
199 rtl_uString
* pustrDirectoryURL
,
200 oslFileHandle
* pHandle
,
201 rtl_uString
** ppustrTempFileURL
)
203 rtl_uString
* base_directory
= 0;
205 sal_Bool b_delete_on_close
;
206 oslFileError osl_error
;
208 osl_error
= osl_setup_createTempFile_impl_(
215 if (osl_File_E_None
!= osl_error
)
218 /* allocate enough space on the stack */
219 STACK_ALLOC(tmp_name
, WCHAR
, (rtl_uString_getLength(base_directory
) + MAX_PATH
));
223 osl_createTempFile_impl_(
230 else // stack alloc failed
232 osl_error
= osl_File_E_NOMEM
;
236 rtl_uString_release(base_directory
);
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;
253 nLength
= GetTempPathW( ELEMENTS_OF_ARRAY(szBuffer
), lpBuffer
);
254 if ( nLength
> nBufferLength
)
257 lpBuffer
= reinterpret_cast<WCHAR
*>(alloca( sizeof(WCHAR
) * nLength
));
258 nBufferLength
= nLength
- 1;
260 } while ( nLength
> nBufferLength
);
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
);
276 error
= oslTranslateFileError( GetLastError() );