tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / sal / osl / w32 / tempfile.cxx
blob30f879573de4cf3ace4bcf1303c8fa4ddf7862f1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <systools/win32/uwinapi.h>
22 #include <osl/file.h>
23 #include <o3tl/char16_t2wchar_t.hxx>
24 #include <rtl/ustring.hxx>
26 #include "file-impl.hxx"
27 #include "file_error.hxx"
28 #include "file_url.hxx"
29 #include "path_helper.hxx"
31 #include <malloc.h>
32 #include <cassert>
34 // Allocate n number of t's on the stack return a pointer to it in p
35 #define STACK_ALLOC(p, t, n) __try {(p) = static_cast<t*>(_alloca((n)*sizeof(t)));} \
36 __except(EXCEPTION_EXECUTE_HANDLER) {(p) = nullptr;}
38 // Temp file functions
40 static oslFileError osl_setup_base_directory_impl_(
41 rtl_uString* pustrDirectoryURL,
42 rtl_uString** ppustr_base_dir)
44 OUString dir_url;
45 OUString dir;
46 oslFileError error = osl_File_E_None;
48 if (pustrDirectoryURL)
49 dir_url = pustrDirectoryURL;
50 else
51 error = osl_getTempDirURL(&dir_url.pData);
53 if (error == osl_File_E_None)
54 error = osl_getSystemPathFromFileURL_(dir_url, &dir.pData, false);
56 if (error == osl_File_E_None)
57 rtl_uString_assign(ppustr_base_dir, dir.pData);
59 return error;
62 static oslFileError osl_setup_createTempFile_impl_(
63 rtl_uString* pustrDirectoryURL,
64 oslFileHandle* pHandle,
65 rtl_uString** ppustrTempFileURL,
66 rtl_uString** ppustr_base_dir,
67 sal_Bool* b_delete_on_close)
69 oslFileError osl_error;
71 OSL_PRECOND(((pHandle != nullptr) || (ppustrTempFileURL != nullptr)), "Invalid parameter!");
73 if ((pHandle == nullptr) && (ppustrTempFileURL == nullptr))
75 osl_error = osl_File_E_INVAL;
77 else
79 osl_error = osl_setup_base_directory_impl_(
80 pustrDirectoryURL, ppustr_base_dir);
82 *b_delete_on_close = (ppustrTempFileURL == nullptr);
85 return osl_error;
88 static LPCWSTR getEyeCatcher()
90 static const OUString sEyeCatcher = []
92 OUString eyeCatcher = u"\0"_ustr;
93 #ifdef DBG_UTIL
94 if (const wchar_t* eye = _wgetenv(L"LO_TESTNAME"))
95 eyeCatcher = OUString(o3tl::toU(eye), wcslen(eye) + 1); // including terminating nul
96 #endif
97 return eyeCatcher;
98 }();
99 return o3tl::toW(sEyeCatcher.getStr());
102 static oslFileError osl_win32_GetTempFileName_impl_(
103 rtl_uString* base_directory, LPWSTR temp_file_name)
105 oslFileError osl_error = osl_File_E_None;
107 if (GetTempFileNameW(
108 o3tl::toW(rtl_uString_getStr(base_directory)),
109 getEyeCatcher(),
111 temp_file_name) == 0)
113 osl_error = oslTranslateFileError(GetLastError());
116 return osl_error;
119 static bool osl_win32_CreateFile_impl_(
120 LPCWSTR file_name, bool b_delete_on_close, oslFileHandle* p_handle)
122 DWORD flags = FILE_ATTRIBUTE_NORMAL;
123 HANDLE hFile;
125 assert(p_handle);
127 if (b_delete_on_close)
128 flags |= FILE_FLAG_DELETE_ON_CLOSE;
130 hFile = CreateFileW(
131 file_name,
132 GENERIC_READ | GENERIC_WRITE,
134 nullptr,
135 TRUNCATE_EXISTING,
136 flags,
137 nullptr);
139 // @@@ ERROR HANDLING @@@
140 if (IsValidHandle(hFile))
141 *p_handle = osl_createFileHandleFromOSHandle(hFile, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write);
143 return IsValidHandle(hFile);
146 static oslFileError osl_createTempFile_impl_(
147 rtl_uString* base_directory,
148 LPWSTR tmp_name,
149 bool b_delete_on_close,
150 oslFileHandle* pHandle,
151 rtl_uString** ppustrTempFileURL)
153 oslFileError osl_error;
157 osl_error = osl_win32_GetTempFileName_impl_(base_directory, tmp_name);
159 /* if file could not be opened try again */
161 if ((osl_File_E_None != osl_error) || (nullptr == pHandle) ||
162 osl_win32_CreateFile_impl_(tmp_name, b_delete_on_close, pHandle))
163 break;
165 } while(true); // try until success
167 if ((osl_error == osl_File_E_None) && !b_delete_on_close)
169 rtl_uString* pustr = nullptr;
170 rtl_uString_newFromStr(&pustr, o3tl::toU(tmp_name));
171 osl_getFileURLFromSystemPath(pustr, ppustrTempFileURL);
172 rtl_uString_release(pustr);
175 return osl_error;
178 oslFileError SAL_CALL osl_createTempFile(
179 rtl_uString* pustrDirectoryURL,
180 oslFileHandle* pHandle,
181 rtl_uString** ppustrTempFileURL)
183 rtl_uString* base_directory = nullptr;
184 LPWSTR tmp_name;
185 sal_Bool b_delete_on_close;
186 oslFileError osl_error;
188 osl_error = osl_setup_createTempFile_impl_(
189 pustrDirectoryURL,
190 pHandle,
191 ppustrTempFileURL,
192 &base_directory,
193 &b_delete_on_close);
195 if (osl_error != osl_File_E_None)
196 return osl_error;
198 /* allocate enough space on the stack, the file name can not be longer than MAX_PATH */
199 STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH));
201 if (tmp_name)
203 osl_error = osl_createTempFile_impl_(
204 base_directory,
205 tmp_name,
206 b_delete_on_close,
207 pHandle,
208 ppustrTempFileURL);
210 else // stack alloc failed
212 osl_error = osl_File_E_NOMEM;
215 if (base_directory)
216 rtl_uString_release(base_directory);
218 return osl_error;
221 oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir)
223 ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
224 LPWSTR lpBuffer = o3tl::toW(aBuffer);
225 DWORD nBufferLength = aBuffer.getBufSizeInSymbols() - 1;
227 DWORD nLength;
228 oslFileError error;
230 nLength = GetTempPathW( aBuffer.getBufSizeInSymbols(), lpBuffer );
232 if ( nLength > nBufferLength )
234 // the provided path has invalid length
235 error = osl_File_E_NOENT;
237 else if ( nLength )
239 if ( '\\' == lpBuffer[nLength-1] )
240 --nLength;
242 const OUString ustrTempPath(o3tl::toU(lpBuffer), static_cast<sal_Int32>(nLength));
244 error = osl_getFileURLFromSystemPath(ustrTempPath.pData, pustrTempDir);
246 else
247 error = oslTranslateFileError( GetLastError() );
249 return error;
252 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */