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