xref: /trunk/main/sal/osl/w32/tempfile.cxx (revision 87d2adbc)
1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*87d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*87d2adbcSAndrew Rist  * distributed with this work for additional information
6*87d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*87d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*87d2adbcSAndrew Rist  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*87d2adbcSAndrew Rist  *
13*87d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist  * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*87d2adbcSAndrew Rist  * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist  * under the License.
19*87d2adbcSAndrew Rist  *
20*87d2adbcSAndrew Rist  *************************************************************/
21*87d2adbcSAndrew Rist 
22*87d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #define UNICODE
25cdf0e10cSrcweir #define _UNICODE
26cdf0e10cSrcweir #define _WIN32_WINNT_0x0500
27cdf0e10cSrcweir #include "systools/win32/uwinapi.h"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "osl/file.h"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "file_error.h"
32cdf0e10cSrcweir #include "file_url.h"
33cdf0e10cSrcweir #include "path_helper.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include "osl/diagnose.h"
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <malloc.h>
38cdf0e10cSrcweir #include <tchar.h>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir //#####################################################
41cdf0e10cSrcweir #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
42cdf0e10cSrcweir 
43cdf0e10cSrcweir // Allocate n number of t's on the stack return a pointer to it in p
44cdf0e10cSrcweir #ifdef __MINGW32__
45cdf0e10cSrcweir #define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));
46cdf0e10cSrcweir #else
47cdf0e10cSrcweir #define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \
48cdf0e10cSrcweir                              __except(EXCEPTION_EXECUTE_HANDLER) {(p) = 0;}
49cdf0e10cSrcweir #endif
50cdf0e10cSrcweir 
51cdf0e10cSrcweir extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle(HANDLE hFile, sal_uInt32 uFlags);
52cdf0e10cSrcweir 
53cdf0e10cSrcweir //#####################################################
54cdf0e10cSrcweir // Temp file functions
55cdf0e10cSrcweir //#####################################################
56cdf0e10cSrcweir 
osl_setup_base_directory_impl_(rtl_uString * pustrDirectoryURL,rtl_uString ** ppustr_base_dir)57cdf0e10cSrcweir static oslFileError osl_setup_base_directory_impl_(
58cdf0e10cSrcweir 	rtl_uString*  pustrDirectoryURL,
59cdf0e10cSrcweir 	rtl_uString** ppustr_base_dir)
60cdf0e10cSrcweir {
61cdf0e10cSrcweir 	rtl_uString* dir_url = 0;
62cdf0e10cSrcweir 	rtl_uString* dir     = 0;
63cdf0e10cSrcweir 	oslFileError error   = osl_File_E_None;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 	if (pustrDirectoryURL)
66cdf0e10cSrcweir 		rtl_uString_assign(&dir_url, pustrDirectoryURL);
67cdf0e10cSrcweir 	else
68cdf0e10cSrcweir 		error = osl_getTempDirURL(&dir_url);
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 	if (osl_File_E_None == error)
71cdf0e10cSrcweir 	{
72cdf0e10cSrcweir         error = _osl_getSystemPathFromFileURL(dir_url, &dir, sal_False);
73cdf0e10cSrcweir         rtl_uString_release(dir_url);
74cdf0e10cSrcweir 	}
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 	if (osl_File_E_None == error )
77cdf0e10cSrcweir 	{
78cdf0e10cSrcweir 		rtl_uString_assign(ppustr_base_dir, dir);
79cdf0e10cSrcweir 		rtl_uString_release(dir);
80cdf0e10cSrcweir 	}
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 	return error;
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir //#####################################################
osl_setup_createTempFile_impl_(rtl_uString * pustrDirectoryURL,oslFileHandle * pHandle,rtl_uString ** ppustrTempFileURL,rtl_uString ** ppustr_base_dir,sal_Bool * b_delete_on_close)86cdf0e10cSrcweir static oslFileError osl_setup_createTempFile_impl_(
87cdf0e10cSrcweir 	rtl_uString*   pustrDirectoryURL,
88cdf0e10cSrcweir 	oslFileHandle* pHandle,
89cdf0e10cSrcweir 	rtl_uString**  ppustrTempFileURL,
90cdf0e10cSrcweir 	rtl_uString**  ppustr_base_dir,
91cdf0e10cSrcweir 	sal_Bool*      b_delete_on_close)
92cdf0e10cSrcweir {
93cdf0e10cSrcweir 	oslFileError osl_error;
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	OSL_PRECOND(((0 != pHandle) || (0 != ppustrTempFileURL)), "Invalid parameter!");
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 	if ((0 == pHandle) && (0 == ppustrTempFileURL))
98cdf0e10cSrcweir 	{
99cdf0e10cSrcweir 		osl_error = osl_File_E_INVAL;
100cdf0e10cSrcweir 	}
101cdf0e10cSrcweir 	else
102cdf0e10cSrcweir 	{
103cdf0e10cSrcweir 		osl_error = osl_setup_base_directory_impl_(
104cdf0e10cSrcweir 			pustrDirectoryURL, ppustr_base_dir);
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 		*b_delete_on_close = (sal_Bool)(0 == ppustrTempFileURL);
107cdf0e10cSrcweir 	}
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 	return osl_error;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir //#####################################################
osl_win32_GetTempFileName_impl_(rtl_uString * base_directory,LPWSTR temp_file_name)113cdf0e10cSrcweir static oslFileError osl_win32_GetTempFileName_impl_(
114cdf0e10cSrcweir 	rtl_uString* base_directory, LPWSTR temp_file_name)
115cdf0e10cSrcweir {
116cdf0e10cSrcweir 	oslFileError osl_error = osl_File_E_None;
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 	if (0 == GetTempFileNameW(
119cdf0e10cSrcweir 			reinterpret_cast<LPCWSTR>(rtl_uString_getStr(base_directory)),
120cdf0e10cSrcweir 			L"",
121cdf0e10cSrcweir 			0,
122cdf0e10cSrcweir 			temp_file_name))
123cdf0e10cSrcweir 	{
124cdf0e10cSrcweir 		osl_error = oslTranslateFileError(GetLastError());
125cdf0e10cSrcweir 	}
126cdf0e10cSrcweir 
127cdf0e10cSrcweir 	return osl_error;
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir //#####################################################
osl_win32_CreateFile_impl_(LPCWSTR file_name,sal_Bool b_delete_on_close,oslFileHandle * p_handle)131cdf0e10cSrcweir static sal_Bool osl_win32_CreateFile_impl_(
132cdf0e10cSrcweir 	LPCWSTR file_name, sal_Bool b_delete_on_close, oslFileHandle* p_handle)
133cdf0e10cSrcweir {
134cdf0e10cSrcweir 	DWORD  flags = FILE_ATTRIBUTE_NORMAL;
135cdf0e10cSrcweir 	HANDLE hFile;
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 	OSL_ASSERT(p_handle);
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 	if (b_delete_on_close)
140cdf0e10cSrcweir 		flags |= FILE_FLAG_DELETE_ON_CLOSE;
141cdf0e10cSrcweir 
142cdf0e10cSrcweir 	hFile = CreateFileW(
143cdf0e10cSrcweir 		file_name,
144cdf0e10cSrcweir 		GENERIC_READ | GENERIC_WRITE,
145cdf0e10cSrcweir 		0,
146cdf0e10cSrcweir 		NULL,
147cdf0e10cSrcweir 		TRUNCATE_EXISTING,
148cdf0e10cSrcweir 		flags,
149cdf0e10cSrcweir 		NULL);
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 	// @@@ ERROR HANDLING @@@
152cdf0e10cSrcweir 	if (IsValidHandle(hFile))
153cdf0e10cSrcweir 		*p_handle = osl_createFileHandleFromOSHandle(hFile, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write);
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 	return (sal_Bool)IsValidHandle(hFile);
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir //#############################################
osl_createTempFile_impl_(rtl_uString * base_directory,LPWSTR tmp_name,sal_Bool b_delete_on_close,oslFileHandle * pHandle,rtl_uString ** ppustrTempFileURL)159cdf0e10cSrcweir static oslFileError osl_createTempFile_impl_(
160cdf0e10cSrcweir 	rtl_uString*   base_directory,
161cdf0e10cSrcweir 	LPWSTR         tmp_name,
162cdf0e10cSrcweir 	sal_Bool       b_delete_on_close,
163cdf0e10cSrcweir 	oslFileHandle* pHandle,
164cdf0e10cSrcweir 	rtl_uString**  ppustrTempFileURL)
165cdf0e10cSrcweir {
166cdf0e10cSrcweir 	oslFileError osl_error;
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 	do
169cdf0e10cSrcweir 	{
170cdf0e10cSrcweir 		osl_error = osl_win32_GetTempFileName_impl_(base_directory, tmp_name);
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 		/*  if file could not be opened try again */
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 		if ((osl_File_E_None != osl_error) || (0 == pHandle) ||
175cdf0e10cSrcweir 			osl_win32_CreateFile_impl_(tmp_name, b_delete_on_close, pHandle))
176cdf0e10cSrcweir 			break;
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 	} while(1); // try until success
179cdf0e10cSrcweir 
180cdf0e10cSrcweir 	if ((osl_File_E_None == osl_error) && !b_delete_on_close)
181cdf0e10cSrcweir 	{
182cdf0e10cSrcweir 		rtl_uString* pustr = 0;
183cdf0e10cSrcweir 		rtl_uString_newFromStr(&pustr, reinterpret_cast<const sal_Unicode*>(tmp_name));
184cdf0e10cSrcweir 		osl_getFileURLFromSystemPath(pustr, ppustrTempFileURL);
185cdf0e10cSrcweir 		rtl_uString_release(pustr);
186cdf0e10cSrcweir 	}
187cdf0e10cSrcweir 
188cdf0e10cSrcweir 	return osl_error;
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir //#############################################
osl_createTempFile(rtl_uString * pustrDirectoryURL,oslFileHandle * pHandle,rtl_uString ** ppustrTempFileURL)192cdf0e10cSrcweir oslFileError SAL_CALL osl_createTempFile(
193cdf0e10cSrcweir     rtl_uString*   pustrDirectoryURL,
194cdf0e10cSrcweir     oslFileHandle* pHandle,
195cdf0e10cSrcweir     rtl_uString**  ppustrTempFileURL)
196cdf0e10cSrcweir {
197cdf0e10cSrcweir     rtl_uString*    base_directory = 0;
198cdf0e10cSrcweir     LPWSTR          tmp_name;
199cdf0e10cSrcweir     sal_Bool        b_delete_on_close;
200cdf0e10cSrcweir     oslFileError    osl_error;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir     osl_error = osl_setup_createTempFile_impl_(
203cdf0e10cSrcweir         pustrDirectoryURL,
204cdf0e10cSrcweir         pHandle,
205cdf0e10cSrcweir         ppustrTempFileURL,
206cdf0e10cSrcweir         &base_directory,
207cdf0e10cSrcweir         &b_delete_on_close);
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     if (osl_File_E_None != osl_error)
210cdf0e10cSrcweir         return osl_error;
211cdf0e10cSrcweir 
212cdf0e10cSrcweir     /* allocate enough space on the stack, the file name can not be longer than MAX_PATH */
213cdf0e10cSrcweir     STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH));
214cdf0e10cSrcweir 
215cdf0e10cSrcweir     if (tmp_name)
216cdf0e10cSrcweir     {
217cdf0e10cSrcweir         osl_createTempFile_impl_(
218cdf0e10cSrcweir             base_directory,
219cdf0e10cSrcweir             tmp_name,
220cdf0e10cSrcweir             b_delete_on_close,
221cdf0e10cSrcweir             pHandle,
222cdf0e10cSrcweir             ppustrTempFileURL);
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir     else // stack alloc failed
225cdf0e10cSrcweir     {
226cdf0e10cSrcweir         osl_error = osl_File_E_NOMEM;
227cdf0e10cSrcweir     }
228cdf0e10cSrcweir 
229cdf0e10cSrcweir     if (base_directory)
230cdf0e10cSrcweir         rtl_uString_release(base_directory);
231cdf0e10cSrcweir 
232cdf0e10cSrcweir     return osl_error;
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir //#############################################
osl_getTempDirURL(rtl_uString ** pustrTempDir)236cdf0e10cSrcweir oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir)
237cdf0e10cSrcweir {
238cdf0e10cSrcweir     ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
239cdf0e10cSrcweir 	LPWSTR	lpBuffer = ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer);
240cdf0e10cSrcweir 	DWORD	nBufferLength = aBuffer.getBufSizeInSymbols() - 1;
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 	DWORD			nLength;
243cdf0e10cSrcweir 	oslFileError	error;
244cdf0e10cSrcweir 
245cdf0e10cSrcweir     nLength = GetTempPathW( aBuffer.getBufSizeInSymbols(), lpBuffer );
246cdf0e10cSrcweir 
247cdf0e10cSrcweir     if ( nLength > nBufferLength )
248cdf0e10cSrcweir     {
249cdf0e10cSrcweir         // the provided path has invalid length
250cdf0e10cSrcweir         error = osl_File_E_NOENT;
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir     else if ( nLength )
253cdf0e10cSrcweir 	{
254cdf0e10cSrcweir 		rtl_uString	*ustrTempPath = NULL;
255cdf0e10cSrcweir 
256cdf0e10cSrcweir 		if ( '\\' == lpBuffer[nLength-1] )
257cdf0e10cSrcweir 			lpBuffer[nLength-1] = 0;
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 		rtl_uString_newFromStr( &ustrTempPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) );
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 		error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir );
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 		rtl_uString_release( ustrTempPath );
264cdf0e10cSrcweir 	}
265cdf0e10cSrcweir 	else
266cdf0e10cSrcweir 		error = oslTranslateFileError( GetLastError() );
267cdf0e10cSrcweir 
268cdf0e10cSrcweir 	return error;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271