summaryrefslogtreecommitdiff
path: root/sal/osl/w32/tempfile.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl/w32/tempfile.cxx')
-rw-r--r--sal/osl/w32/tempfile.cxx274
1 files changed, 274 insertions, 0 deletions
diff --git a/sal/osl/w32/tempfile.cxx b/sal/osl/w32/tempfile.cxx
new file mode 100644
index 000000000000..4bf136b6b0e0
--- /dev/null
+++ b/sal/osl/w32/tempfile.cxx
@@ -0,0 +1,274 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define UNICODE
+#define _UNICODE
+#define _WIN32_WINNT_0x0500
+#include "systools/win32/uwinapi.h"
+
+#include "osl/file.h"
+
+#include "file_error.h"
+#include "file_url.h"
+#include "path_helper.hxx"
+
+#include "osl/diagnose.h"
+
+#include <malloc.h>
+#include <tchar.h>
+
+//#####################################################
+#define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
+
+// Allocate n number of t's on the stack return a pointer to it in p
+#ifdef __MINGW32__
+#define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));
+#else
+#define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \
+ __except(EXCEPTION_EXECUTE_HANDLER) {(p) = 0;}
+#endif
+
+extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle(HANDLE hFile, sal_uInt32 uFlags);
+
+//#####################################################
+// Temp file functions
+//#####################################################
+
+static oslFileError osl_setup_base_directory_impl_(
+ rtl_uString* pustrDirectoryURL,
+ rtl_uString** ppustr_base_dir)
+{
+ rtl_uString* dir_url = 0;
+ rtl_uString* dir = 0;
+ oslFileError error = osl_File_E_None;
+
+ if (pustrDirectoryURL)
+ rtl_uString_assign(&dir_url, pustrDirectoryURL);
+ else
+ error = osl_getTempDirURL(&dir_url);
+
+ if (osl_File_E_None == error)
+ {
+ error = _osl_getSystemPathFromFileURL(dir_url, &dir, sal_False);
+ rtl_uString_release(dir_url);
+ }
+
+ if (osl_File_E_None == error )
+ {
+ rtl_uString_assign(ppustr_base_dir, dir);
+ rtl_uString_release(dir);
+ }
+
+ return error;
+}
+
+//#####################################################
+static oslFileError osl_setup_createTempFile_impl_(
+ rtl_uString* pustrDirectoryURL,
+ oslFileHandle* pHandle,
+ rtl_uString** ppustrTempFileURL,
+ rtl_uString** ppustr_base_dir,
+ sal_Bool* b_delete_on_close)
+{
+ oslFileError osl_error;
+
+ OSL_PRECOND(((0 != pHandle) || (0 != ppustrTempFileURL)), "Invalid parameter!");
+
+ if ((0 == pHandle) && (0 == ppustrTempFileURL))
+ {
+ osl_error = osl_File_E_INVAL;
+ }
+ else
+ {
+ osl_error = osl_setup_base_directory_impl_(
+ pustrDirectoryURL, ppustr_base_dir);
+
+ *b_delete_on_close = (sal_Bool)(0 == ppustrTempFileURL);
+ }
+
+ return osl_error;
+}
+
+//#####################################################
+static oslFileError osl_win32_GetTempFileName_impl_(
+ rtl_uString* base_directory, LPWSTR temp_file_name)
+{
+ oslFileError osl_error = osl_File_E_None;
+
+ if (0 == GetTempFileNameW(
+ reinterpret_cast<LPCWSTR>(rtl_uString_getStr(base_directory)),
+ L"",
+ 0,
+ temp_file_name))
+ {
+ osl_error = oslTranslateFileError(GetLastError());
+ }
+
+ return osl_error;
+}
+
+//#####################################################
+static sal_Bool osl_win32_CreateFile_impl_(
+ LPCWSTR file_name, sal_Bool b_delete_on_close, oslFileHandle* p_handle)
+{
+ DWORD flags = FILE_ATTRIBUTE_NORMAL;
+ HANDLE hFile;
+
+ OSL_ASSERT(p_handle);
+
+ if (b_delete_on_close)
+ flags |= FILE_FLAG_DELETE_ON_CLOSE;
+
+ hFile = CreateFileW(
+ file_name,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ TRUNCATE_EXISTING,
+ flags,
+ NULL);
+
+ // @@@ ERROR HANDLING @@@
+ if (IsValidHandle(hFile))
+ *p_handle = osl_createFileHandleFromOSHandle(hFile, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write);
+
+ return (sal_Bool)IsValidHandle(hFile);
+}
+
+//#############################################
+static oslFileError osl_createTempFile_impl_(
+ rtl_uString* base_directory,
+ LPWSTR tmp_name,
+ sal_Bool b_delete_on_close,
+ oslFileHandle* pHandle,
+ rtl_uString** ppustrTempFileURL)
+{
+ oslFileError osl_error;
+
+ do
+ {
+ osl_error = osl_win32_GetTempFileName_impl_(base_directory, tmp_name);
+
+ /* if file could not be opened try again */
+
+ if ((osl_File_E_None != osl_error) || (0 == pHandle) ||
+ osl_win32_CreateFile_impl_(tmp_name, b_delete_on_close, pHandle))
+ break;
+
+ } while(1); // try until success
+
+ if ((osl_File_E_None == osl_error) && !b_delete_on_close)
+ {
+ rtl_uString* pustr = 0;
+ rtl_uString_newFromStr(&pustr, reinterpret_cast<const sal_Unicode*>(tmp_name));
+ osl_getFileURLFromSystemPath(pustr, ppustrTempFileURL);
+ rtl_uString_release(pustr);
+ }
+
+ return osl_error;
+}
+
+//#############################################
+oslFileError SAL_CALL osl_createTempFile(
+ rtl_uString* pustrDirectoryURL,
+ oslFileHandle* pHandle,
+ rtl_uString** ppustrTempFileURL)
+{
+ rtl_uString* base_directory = 0;
+ LPWSTR tmp_name;
+ sal_Bool b_delete_on_close;
+ oslFileError osl_error;
+
+ osl_error = osl_setup_createTempFile_impl_(
+ pustrDirectoryURL,
+ pHandle,
+ ppustrTempFileURL,
+ &base_directory,
+ &b_delete_on_close);
+
+ if (osl_File_E_None != osl_error)
+ return osl_error;
+
+ /* allocate enough space on the stack, the file name can not be longer than MAX_PATH */
+ STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH));
+
+ if (tmp_name)
+ {
+ osl_createTempFile_impl_(
+ base_directory,
+ tmp_name,
+ b_delete_on_close,
+ pHandle,
+ ppustrTempFileURL);
+ }
+ else // stack alloc failed
+ {
+ osl_error = osl_File_E_NOMEM;
+ }
+
+ if (base_directory)
+ rtl_uString_release(base_directory);
+
+ return osl_error;
+}
+
+//#############################################
+oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir)
+{
+ ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
+ LPWSTR lpBuffer = aBuffer;
+ DWORD nBufferLength = aBuffer.getBufSizeInSymbols() - 1;
+
+ DWORD nLength;
+ oslFileError error;
+
+ nLength = GetTempPathW( aBuffer.getBufSizeInSymbols(), lpBuffer );
+
+ if ( nLength > nBufferLength )
+ {
+ // the provided path has invalid length
+ error = osl_File_E_NOENT;
+ }
+ else if ( nLength )
+ {
+ rtl_uString *ustrTempPath = NULL;
+
+ if ( '\\' == lpBuffer[nLength-1] )
+ lpBuffer[nLength-1] = 0;
+
+ rtl_uString_newFromStr( &ustrTempPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) );
+
+ error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir );
+
+ rtl_uString_release( ustrTempPath );
+ }
+ else
+ error = oslTranslateFileError( GetLastError() );
+
+ return error;
+}
+