summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2009-09-09 09:38:41 +0000
committerOliver Bolte <obo@openoffice.org>2009-09-09 09:38:41 +0000
commitd173c0fd1b1d7316d30640edfe307daf83d631fa (patch)
tree8ad39ecf8b5da036108e6f3a1a9b2770d5fce22e
parent69a912dcc065d463ff6a4000667b8d9b8be06178 (diff)
CWS-TOOLING: integrate CWS mhu20
2009-09-01 15:18:43 +0200 mhu r275662 : #i32526# Fixed missing includes, and a wrong cast 2009-08-28 13:30:05 +0200 mhu r275530 : #i32526# Fixed missing includes and remaining merge conflicts. 2009-08-28 13:28:45 +0200 mhu r275529 : #i32526# osl_readLine() now implemented in sal/osl/<platform>/file.cxx 2009-08-26 19:47:53 +0200 mhu r275445 : CWS-TOOLING: rebase CWS mhu20 to trunk@275331 (milestone: DEV300:m56) 2009-08-25 15:47:00 +0200 mhu r275365 : #i32526# Also maintain phys. file offset. 2009-08-25 15:24:56 +0200 mhu r275364 : #i32526# Added buffered file I/O; refactored file.cxx into multiple files. 2009-08-24 10:38:15 +0200 mhu r275294 : #i32526# Correct OpenFlags for osl_openFile(). 2009-05-25 11:07:34 +0200 mhu r272225 : #i32526# Added support for non-seekable file handles (pipe et al.). 2009-05-25 11:01:50 +0200 mhu r272223 : #i32526# Add osl_readLine() test, cleanup obsolete tests. 2009-05-25 10:56:14 +0200 mhu r272221 : #i32526# Add missing include 2009-05-25 10:48:51 +0200 mhu r272220 : #i32526# Accept OpenJDK (IcedTea6) 1.6.0_0 version string 2009-05-15 19:18:20 +0200 mhu r271965 : #i32526# Initial osl/unx buffered file I/O implementation. 2009-05-15 17:41:57 +0200 mhu r271959 : CWS-TOOLING: rebase CWS mhu20 to trunk@271830 (milestone: DEV300:m48) 2009-03-26 17:28:53 +0100 mhu r270091 : CWS-TOOLING: rebase CWS mhu20 to trunk@270033 (milestone: DEV300:m45)
-rw-r--r--jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx2
-rw-r--r--jvmfwk/plugins/sunmajor/pluginlib/util.cxx18
-rw-r--r--sal/osl/all/makefile.mk6
-rw-r--r--sal/osl/all/readline.c311
-rw-r--r--sal/osl/unx/file.cxx4121
-rw-r--r--sal/osl/unx/file_impl.hxx43
-rw-r--r--sal/osl/unx/file_misc.cxx1084
-rw-r--r--sal/osl/unx/file_stat.cxx281
-rw-r--r--sal/osl/unx/file_url.cxx177
-rw-r--r--sal/osl/unx/file_url.h60
-rw-r--r--sal/osl/unx/file_volume.cxx1570
-rw-r--r--sal/osl/unx/makefile.mk12
-rw-r--r--sal/osl/w32/MAKEFILE.MK8
-rw-r--r--sal/osl/w32/file.cxx4019
-rw-r--r--sal/osl/w32/file_dirvol.cxx1774
-rw-r--r--sal/osl/w32/file_error.c154
-rw-r--r--sal/osl/w32/file_error.h54
-rw-r--r--sal/osl/w32/file_url.cxx1013
-rw-r--r--sal/osl/w32/file_url.h95
-rw-r--r--sal/osl/w32/procimpl.cxx8
-rw-r--r--sal/osl/w32/tempfile.cxx279
-rw-r--r--sal/workben/makefile.mk23
-rw-r--r--sal/workben/t_layer.c314
-rw-r--r--sal/workben/t_readline.c58
-rw-r--r--sal/workben/t_tls.c257
-rw-r--r--sal/workben/t_zip.c183
-rw-r--r--store/source/lockbyte.cxx2
-rw-r--r--store/workben/makefile.mk11
28 files changed, 8108 insertions, 7829 deletions
diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx
index f0ceaeef3..ae0b76b4a 100644
--- a/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx
+++ b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx
@@ -159,7 +159,7 @@ bool SunVersion::init(const char *szVersion)
{
//1.4.1_01-, 1.4.1_01a, the numerical part may only be 2 chars.
int len = pCur - pLast;
- if (len != 2)
+ if (len > 2)
return false;
//we've got the update: 01, 02 etc
strncpy(buf, pLast, len);
diff --git a/jvmfwk/plugins/sunmajor/pluginlib/util.cxx b/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
index 45f9e8019..abc283c5c 100644
--- a/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
+++ b/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
@@ -241,9 +241,9 @@ FileHandleReader::readLine(rtl::OString * pLine)
{
if (m_nIndex == m_nSize)
{
- sal_uInt64 nRead;
+ sal_uInt64 nRead = 0;
switch (osl_readFile(
- m_aGuard.getHandle(), m_aBuffer, BUFFER_SIZE, &nRead))
+ m_aGuard.getHandle(), m_aBuffer, sizeof(m_aBuffer), &nRead))
{
case osl_File_E_PIPE: //HACK! for windows
nRead = 0;
@@ -256,8 +256,8 @@ FileHandleReader::readLine(rtl::OString * pLine)
m_nIndex = 0;
m_nSize = static_cast< int >(nRead);
break;
- case osl_File_E_INTR:
- continue;
+ case osl_File_E_INTR:
+ continue;
default:
return RESULT_ERROR;
@@ -483,19 +483,21 @@ bool getJavaProps(const OUString & exePath,
*/
rtl::OUString decodeOutput(const rtl::OString& s)
{
- OUString sEncoded = OStringToOUString(s, RTL_TEXTENCODING_ASCII_US);
OUStringBuffer buff(512);
sal_Int32 nIndex = 0;
do
{
- OUString aToken = sEncoded.getToken( 0, ' ', nIndex );
+ OString aToken = s.getToken( 0, ' ', nIndex );
if (aToken.getLength())
{
- sal_Unicode value = (sal_Unicode) aToken.toInt32();
+ sal_Unicode value = (sal_Unicode)(aToken.toInt32());
buff.append(value);
}
} while (nIndex >= 0);
- return buff.makeStringAndClear();
+
+ OUString sDecoded(buff.makeStringAndClear());
+ JFW_TRACE2(sDecoded);
+ return sDecoded;
}
diff --git a/sal/osl/all/makefile.mk b/sal/osl/all/makefile.mk
index 6bed1c53c..bbb46b89d 100644
--- a/sal/osl/all/makefile.mk
+++ b/sal/osl/all/makefile.mk
@@ -57,18 +57,20 @@ CXXFLAGS+= $(LFS_CFLAGS)
SLOFILES= \
$(SLO)$/utility.obj\
- $(SLO)$/readline.obj\
$(SLO)$/filepath.obj\
$(SLO)$/debugbase.obj\
$(SLO)$/loadmodulerelative.obj
+# $(SLO)$/readline.obj\
+
#.IF "$(UPDATER)"=="YES"
OBJFILES= \
$(OBJ)$/utility.obj\
- $(OBJ)$/readline.obj\
$(OBJ)$/filepath.obj\
$(OBJ)$/debugbase.obj\
$(OBJ)$/loadmodulerelative.obj
+
+# $(OBJ)$/readline.obj\
#.ENDIF
# --- Targets ------------------------------------------------------
diff --git a/sal/osl/all/readline.c b/sal/osl/all/readline.c
deleted file mode 100644
index e5baa4f96..000000000
--- a/sal/osl/all/readline.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: readline.c,v $
- * $Revision: 1.9 $
- *
- * 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.
- *
- ************************************************************************/
-
-#include <osl/diagnose.h>
-#include <osl/file.h>
-#include <rtl/byteseq.h>
-#include <rtl/alloc.h>
-
-
-/* Test cases:
-
- 1. A file without line ends
- 2. A file with lines longer than the initial buffer size
- 3. An empty file
- 4.
-*/
-
-/** Some defines
-*/
-#define CR 0x0D
-#define LF 0x0A
-
-#define INITIAL_BUFF_SIZE 80
-#define BUFFER_GROW_FACTOR 2
-#define READ_BLOCK_SIZE (INITIAL_BUFF_SIZE - 1)
-
-/** Helper data and function
-*/
-
-struct _Buffer
-{
- sal_Char* m_pMem;
- sal_uInt64 m_Capacity; /* elements possible in buffer */
- sal_uInt64 m_Size; /* elements actually in buffer */
- sal_uInt64 m_ActiveSectionStart; /* buffer was lastly filled from here to
- (m_Size - 1) */
-};
-
-typedef struct _Buffer Buffer;
-
-
-/** Allocate the memory of the buffer
- @Returns sal_True on succes
-*/
-static sal_Bool AllocateBuffer(Buffer* pBuffer, sal_uInt64 Capacity)
-{
- sal_Bool rc = sal_False;
-
- OSL_ASSERT(pBuffer);
-
- pBuffer->m_pMem = (sal_Char*)rtl_allocateZeroMemory((sal_uInt32)Capacity);
- if (pBuffer->m_pMem)
- {
- pBuffer->m_Capacity = Capacity;
- pBuffer->m_Size = 0;
- pBuffer->m_ActiveSectionStart = 0;
- rc = sal_True;
- }
-
- return rc;
-}
-
-/** Release the memory occupied by the buffer
-*/
-static void FreeBuffer(Buffer* pBuffer)
-{
- OSL_ASSERT(pBuffer);
-
- rtl_freeMemory(pBuffer->m_pMem);
- pBuffer->m_pMem = 0;
- pBuffer->m_Capacity = 0;
- pBuffer->m_Size = 0;
- pBuffer->m_ActiveSectionStart = 0;
-}
-
-/** Grow the buffer by the specified factor (usually doubling
- the buffer size)
- In case of failure, growing the buffer, the original buffer
- stays untouched
-
- @Returns sal_True on success
-*/
-static sal_Bool GrowBuffer(Buffer* pBuffer, size_t factor)
-{
- sal_Bool rc = sal_False;
- void* p;
-
- OSL_ASSERT(pBuffer);
-
- p = rtl_reallocateMemory(
- pBuffer->m_pMem, (sal_uInt32)(pBuffer->m_Capacity * factor));
- if (p)
- {
- pBuffer->m_pMem = (sal_Char*)p;
- pBuffer->m_Capacity *= factor;
- rc = sal_True;
- }
-
- return rc;
-}
-
-/** Read n bytes from file into buffer,
- grow the buffer if necessary
-
- @Returns osl_File_E_None on success else
- an error code
-*/
-static oslFileError ReadFromFile(oslFileHandle hFile, Buffer* pBuffer, sal_uInt64 Requested, sal_uInt64* pRead)
-{
- oslFileError rc;
-
- OSL_ASSERT(pBuffer);
- OSL_ASSERT(hFile);
- OSL_ASSERT(pRead);
-
- if (((pBuffer->m_Size + Requested) > pBuffer->m_Capacity) &&
- !GrowBuffer(pBuffer, BUFFER_GROW_FACTOR))
- return osl_File_E_NOMEM;
-
- pBuffer->m_ActiveSectionStart = pBuffer->m_Size;
-
- rc = osl_readFile(
- hFile,
- pBuffer->m_pMem + pBuffer->m_ActiveSectionStart,
- Requested,
- pRead);
-
- if (osl_File_E_None == rc)
- pBuffer->m_Size += *pRead;
-
- return rc;
-}
-
-/** Makes a sequence from the given buffer and release the memory
- occupied by the buffer
-*/
-static void MakeSequenceFreeBuffer(sal_Sequence** ppSequence, Buffer* pBuffer, sal_uInt64 Length)
-{
- OSL_ASSERT(ppSequence);
- OSL_ASSERT(pBuffer);
- OSL_ASSERT(Length <= pBuffer->m_Capacity);
-
- rtl_byte_sequence_constructFromArray(ppSequence, (sal_Int8*)pBuffer->m_pMem, (sal_Int32)Length);
- FreeBuffer(pBuffer);
-}
-
-/** Handle occurence of LF character:
- construct a sequence from buffer
- correct file pointer (maybe we have read more than necessary)
-
- @Returns osl_File_E_None on success else
- an error code
-*/
-static oslFileError HandleLFFreeBuffer(oslFileHandle hFile, sal_Sequence** ppSequence, Buffer* pBuffer, sal_uInt64 Pos)
-{
- sal_Int64 offset = 0;
- oslFileError rc = osl_File_E_None;
-
- OSL_ASSERT(hFile);
- OSL_ASSERT(pBuffer);
- OSL_ASSERT(LF == pBuffer->m_pMem[Pos]);
-
- /* correct file pointer pos in case we have read to far */
- offset = pBuffer->m_Size - (Pos + 1);
- rc = osl_setFilePos(hFile, osl_Pos_Current, -offset);
-
- if (osl_File_E_None == rc)
- MakeSequenceFreeBuffer(ppSequence, pBuffer, Pos);
- else
- FreeBuffer(pBuffer);
-
- return rc;
-}
-
-/** Handle occurence of CR character
- construct a sequence from buffer
- correct file pointer (maybe we have read more than necessary)
-
- @Returns osl_File_E_None on success else
- an error code
-*/
-static oslFileError HandleCRFreeBuffer(oslFileHandle hFile, sal_Sequence** ppSequence, Buffer* pBuffer, sal_uInt64 Pos)
-{
- sal_Int64 offset = 0;
- sal_uInt64 nread = 0;
- oslFileError rc = osl_File_E_None;
-
- OSL_ASSERT(hFile);
- OSL_ASSERT(pBuffer);
- OSL_ASSERT(CR == pBuffer->m_pMem[Pos]);
-
- if (Pos == (pBuffer->m_Size - 1))
- {
- /* only need to check if the next byte is a LF
- that's why reading only one byte from file */
- rc = ReadFromFile(hFile, pBuffer, 1, &nread);
-
- if (osl_File_E_None != rc)
- {
- FreeBuffer(pBuffer);
- return rc;
- }
- else if (0 == nread)
- {
- MakeSequenceFreeBuffer(ppSequence, pBuffer, Pos);
- return osl_File_E_None;
- }
- }
-
- if (LF == pBuffer->m_pMem[Pos + 1])
- Pos++;
-
- /* correct the file pointer */
- offset = pBuffer->m_Size - (Pos + 1);
- rc = osl_setFilePos(hFile, osl_Pos_Current, -offset);
-
- if (osl_File_E_None == rc)
- MakeSequenceFreeBuffer(ppSequence, pBuffer, Pos - 1);
- else
- FreeBuffer(pBuffer);
-
- return rc;
-}
-
-/***************************************************************************
- osl_readLine (platform independent)
- Reads a line from given file. The new line delimiter(s) are NOT returned!
- Valid line ends: \n, \r\n or \r
-
- @param Handle [in] Handle to an open file.
- @param ppSequence [in/out] a pointer to a valid sequence.
-
- @return osl_File_E_None on success otherwise one of the following errorcodes:<p>
-
- osl_File_E_INVAL the format of the parameters was not valid<br>
- osl_File_E_NOMEM the necessary memory could not be allocated
-****************************************************************************/
-
-oslFileError SAL_CALL osl_readLine(oslFileHandle Handle, sal_Sequence** ppSeq)
-{
- oslFileError rc;
- sal_uInt64 nread = 0;
- Buffer line_buffer;
- sal_uInt64 pos;
-
- OSL_PRECOND(Handle, "invalid handle");
- OSL_PRECOND(ppSeq, "invalid parameter detected");
-
- if (!AllocateBuffer(&line_buffer, INITIAL_BUFF_SIZE))
- return osl_File_E_NOMEM;
-
- for(;;)
- {
- rc = ReadFromFile(Handle, &line_buffer, READ_BLOCK_SIZE, &nread);
-
- if (osl_File_E_None != rc)
- {
- FreeBuffer(&line_buffer);
- return rc;
- }
- else if (0 == nread)
- {
- /* EOF */
- nread = line_buffer.m_Size;
- MakeSequenceFreeBuffer(ppSeq, &line_buffer, nread);
- if (0 < nread)
- return osl_File_E_None;
- else
- return osl_File_E_AGAIN;
- }
-
- /* scan buffer for line end */
- for (pos = line_buffer.m_ActiveSectionStart; pos < line_buffer.m_Size; pos++)
- {
- switch(line_buffer.m_pMem[pos])
- {
- case LF:
- return HandleLFFreeBuffer(Handle, ppSeq, &line_buffer, pos);
- case CR:
- return HandleCRFreeBuffer(Handle, ppSeq, &line_buffer, pos);
- }
- }
- } /* end for */
-}
diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index f15f6bd37..28cc35831 100644
--- a/sal/osl/unx/file.cxx
+++ b/sal/osl/unx/file.cxx
@@ -31,612 +31,730 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"
-
-/************************************************************************
- * ToDo
- *
- * Fix osl_getCanonicalName
- *
- * - Fix: check for corresponding struct sizes in exported functions
- * - check size/use of oslDirectory
- * - check size/use of oslDirectoryItem
- * - check size/use of oslFileStatus
- * - check size/use of oslVolumeDeviceHandle
- * - check size/use of oslVolumeInfo
- * - check size/use of oslFileHandle
- ***********************************************************************/
-
-#include <algorithm>
-#include <limits>
-#include "system.h"
-#include <rtl/alloc.h>
-
#include "osl/file.hxx"
+#include "osl/diagnose.h"
+#include "rtl/alloc.h"
-#include <sal/types.h>
-#include <osl/thread.h>
-#include <osl/diagnose.h>
+#include "system.h"
#include "file_error_transl.h"
-#include <osl/time.h>
-
-#ifndef _FILE_URL_H_
#include "file_url.h"
-#endif
-
-#include "file_path_helper.hxx"
-#include "uunxapi.hxx"
+#include <algorithm>
+#include <limits>
-#include <sys/mman.h>
-
-#ifdef HAVE_STATFS_H
-#undef HAVE_STATFS_H
-#endif
-
-#ifndef _STRING_H
#include <string.h>
-#endif
-
-#if defined(SOLARIS)
-#include <sys/mnttab.h>
-#include <sys/statvfs.h>
-#define HAVE_STATFS_H
-#include <sys/fs/ufs_quota.h>
-static const sal_Char* MOUNTTAB="/etc/mnttab";
-
-#elif defined(LINUX)
-#include <mntent.h>
-#include <sys/vfs.h>
-#define HAVE_STATFS_H
-#include <sys/quota.h>
-#include <ctype.h>
-static const sal_Char* MOUNTTAB="/etc/mtab";
-
-#elif defined(NETBSD) || defined(FREEBSD)
-#include <sys/param.h>
-#include <sys/ucred.h>
-#include <sys/mount.h>
-#include <ufs/ufs/quota.h>
-#include <ctype.h>
-#define HAVE_STATFS_H
-/* No mounting table on *BSD
- * This information is stored only in the kernel. */
-/* static const sal_Char* MOUNTTAB="/etc/mtab"; */
-
-#elif defined(IRIX)
-#include <mntent.h>
-#include <sys/mount.h>
-#include <sys/statvfs.h>
-#define HAVE_STATFS_H
-#include <sys/quota.h>
-#include <ctype.h>
-static const sal_Char* MOUNTTAB="/etc/mtab";
+#include <sys/mman.h>
-#elif defined(MACOSX)
-#include <ufs/ufs/quota.h>
-#include <ctype.h>
-// static const sal_Char* MOUNTTAB="/etc/mtab";
+#if defined(MACOSX)
#include <sys/param.h>
#include <sys/mount.h>
-#define HAVE_STATFS_H
#define HAVE_O_EXLOCK
// add MACOSX Time Value
-
#define TimeValue CFTimeValue
#include <CoreFoundation/CoreFoundation.h>
#undef TimeValue
-#endif
-
-#ifdef _DIRENT_HAVE_D_TYPE
-#include "file_impl.hxx"
- oslDirectoryItemImpl* oslDirectoryItemImpl_CreateNew( rtl_uString* _ustrFilePath, bool _bHasDType, unsigned char _DType )
- {
- oslDirectoryItemImpl *pItemObject = (oslDirectoryItemImpl*) malloc( sizeof( oslDirectoryItemImpl ) );
- pItemObject->RefCount = 1;
- pItemObject->bHasType = _bHasDType;
- pItemObject->DType = _DType;
- pItemObject->ustrFilePath = _ustrFilePath;
-
- return pItemObject;
- }
-
- void oslDirectoryItemImpl_Destroy( oslDirectoryItemImpl* pItem )
- {
- if( pItem->ustrFilePath ) {
- rtl_uString_release( pItem->ustrFilePath );
- pItem->ustrFilePath = NULL;
- }
- free( pItem );
- }
-
- void oslDirectoryItemImpl_acquire( oslDirectoryItemImpl* pItem )
- {
- pItem->RefCount ++;
- }
-
- void oslDirectoryItemImpl_release( oslDirectoryItemImpl* pItem )
- {
- pItem->RefCount --;
-
- if( pItem->RefCount <= 0 )
- oslDirectoryItemImpl_Destroy( pItem );
- }
-#endif
-
-#if OSL_DEBUG_LEVEL > 1
-
- extern void debug_ustring(rtl_uString*);
-
-#endif
-
+#endif /* MACOSX */
#ifdef DEBUG_OSL_FILE
+# define OSL_FILE_TRACE 0 ? (void)(0) : osl_trace
# define PERROR( a, b ) perror( a ); fprintf( stderr, b )
#else
+# define OSL_FILE_TRACE 1 ? (void)(0) : osl_trace
# define PERROR( a, b )
#endif
-extern "C" oslFileHandle osl_createFileHandleFromFD( int fd );
-
-/******************************************************************************
+/*******************************************************************
*
- * Data Type Definition
+ * FileHandle_Impl interface
*
- ******************************************************************************/
-
-#if 0
-/* FIXME: reintroducing this may save some extra bytes per Item */
-typedef struct
-{
- rtl_uString* ustrFileName; /* holds native file name */
- rtl_uString* ustrDirPath; /* holds native dir path */
- sal_uInt32 RefCount;
-} oslDirectoryItemImpl;
-#endif
-
-typedef struct
-{
- rtl_uString* ustrPath; /* holds native directory path */
- DIR* pDirStruct;
-} oslDirectoryImpl;
-
-
-typedef struct
+ ******************************************************************/
+struct FileHandle_Impl
{
- rtl_uString* ustrFilePath; /* holds native file path */
- int fd;
- sal_Bool bLocked;
-} oslFileHandleImpl;
-
+ rtl_String * m_strFilePath; /* holds native file path */
+ int m_fd;
-typedef struct _oslVolumeDeviceHandleImpl
-{
- sal_Char pszMountPoint[PATH_MAX];
- sal_Char pszFilePath[PATH_MAX];
- sal_Char pszDevice[PATH_MAX];
- sal_Char ident[4];
- sal_uInt32 RefCount;
-} oslVolumeDeviceHandleImpl;
+ /** State
+ */
+ enum StateBits
+ {
+ STATE_SEEKABLE = 1, /* default */
+ STATE_READABLE = 2, /* default */
+ STATE_WRITEABLE = 4, /* open() sets, write() requires, else osl_File_E_BADF */
+ STATE_MODIFIED = 8 /* write() sets, flush() resets */
+ };
+ int m_state;
+ sal_uInt64 m_size; /* file size */
+ off_t m_offset; /* physical offset from begin of file */
+ off_t m_fileptr; /* logical offset from begin of file */
-/******************************************************************************
- *
- * static members
- *
- *****************************************************************************/
+ off_t m_bufptr; /* buffer offset from begin of file */
+ size_t m_buflen; /* buffer filled [0, m_bufsiz - 1] */
-static const char * pFileLockEnvVar = (char *) -1;
+ size_t m_bufsiz;
+ sal_uInt8 * m_buffer;
+ explicit FileHandle_Impl (int fd, char const * path = "<anon>");
+ ~FileHandle_Impl();
-/******************************************************************************
- *
- * C-String Function Declarations
- *
- *****************************************************************************/
+ static void* operator new (size_t n);
+ static void operator delete (void * p, size_t);
-static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
-static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
-static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
-static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
-static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
-static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
-static oslFileError osl_psz_setFileAttributes(const sal_Char* pszFilePath, sal_uInt64 uAttributes);
-static oslFileError osl_psz_setFileTime(const sal_Char* strFilePath, const TimeValue* pCreationTime, const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime);
+ static size_t getpagesize();
+ sal_uInt64 getPos() const;
+ oslFileError setPos (sal_uInt64 uPos);
-/******************************************************************************
- *
- * Static Module Utility Function Declarations
- *
- *****************************************************************************/
+ sal_uInt64 getSize() const;
-static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
-static oslFileError oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
-static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
-static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
-static oslFileError oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
-static rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr,rtl_uString** uStr);
+ oslFileError readAt (
+ off_t nOffset,
+ void * pBuffer,
+ size_t nBytesRequested,
+ sal_uInt64 * pBytesRead);
-/******************************************************************************
- *
- * Non-Static Utility Function Declarations
- *
- *****************************************************************************/
+ oslFileError writeAt (
+ off_t nOffset,
+ void const * pBuffer,
+ size_t nBytesToWrite,
+ sal_uInt64 * pBytesWritten);
-extern "C" int UnicodeToText( char *, size_t, const sal_Unicode *, sal_Int32 );
-extern "C" int TextToUnicode(
- const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
+ oslFileError readFileAt (
+ off_t nOffset,
+ void * pBuffer,
+ size_t nBytesRequested,
+ sal_uInt64 * pBytesRead);
-/******************************************************************************
- *
- * 'removeable device' aka floppy functions
- *
- *****************************************************************************/
+ oslFileError writeFileAt (
+ off_t nOffset,
+ void const * pBuffer,
+ size_t nBytesToWrite,
+ sal_uInt64 * pBytesWritten);
-static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath);
-static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy);
-static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy);
+ oslFileError readLineAt (
+ off_t nOffset,
+ sal_Sequence ** ppSequence,
+ sal_uInt64 * pBytesRead);
+ oslFileError writeSequence_Impl (
+ sal_Sequence ** ppSequence,
+ size_t * pnOffset,
+ const void * pBuffer,
+ size_t nBytes);
-#if defined(SOLARIS)
-static sal_Bool osl_isFloppyMounted(sal_Char* pszPath, sal_Char* pszMountPath);
-static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, sal_Char* pBuffer);
-static sal_Bool osl_checkFloppyPath(sal_Char* pszPath, sal_Char* pszFilePath, sal_Char* pszDevicePath);
-#endif
+ oslFileError syncFile();
-#if defined(LINUX)
-static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice);
-static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem);
-#endif
+ /** Buffer cache / allocator.
+ */
+ class Allocator
+ {
+ rtl_cache_type * m_cache;
+ size_t m_bufsiz;
+ Allocator (Allocator const &);
+ Allocator & operator= (Allocator const &);
-#if defined(IRIX)
-static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice);
-static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem);
-#endif
+ public:
+ static Allocator & get();
-#ifdef DEBUG_OSL_FILE
-static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
-#endif
+ void allocate (sal_uInt8 ** ppBuffer, size_t * pnSize);
+ void deallocate (sal_uInt8 * pBuffer);
-#ifdef MACOSX
+ protected:
+ Allocator();
+ ~Allocator();
+ };
+};
/*******************************************************************
- * adjustLockFlags
+ *
+ * FileHandle_Impl implementation
+ *
******************************************************************/
-/* The AFP implementation of MacOS X 10.4 treats O_EXLOCK in a way
- * that makes it impossible for OOo to create a backup copy of the
- * file it keeps opened. OTOH O_SHLOCK for AFP behaves as desired by
- * the OOo file handling, so we need to check the path of the file
- * for the filesystem name.
- */
-
-static int adjustLockFlags(const char * path, int flags)
+FileHandle_Impl::Allocator &
+FileHandle_Impl::Allocator::get()
{
- struct statfs s;
-
- if( 0 <= statfs( path, &s ) )
+ static Allocator g_aBufferAllocator;
+ return g_aBufferAllocator;
+}
+
+FileHandle_Impl::Allocator::Allocator()
+ : m_cache (0),
+ m_bufsiz (0)
+{
+ size_t const pagesize = FileHandle_Impl::getpagesize();
+ if (size_t(-1) != pagesize)
{
- if( 0 == strncmp("afpfs", s.f_fstypename, 5) )
- {
- flags &= ~O_EXLOCK;
- flags |= O_SHLOCK;
- }
- else
- {
- /* Needed flags to allow opening a webdav file */
- flags &= ~( O_EXLOCK | O_SHLOCK );
- }
+ m_cache = rtl_cache_create (
+ "osl_file_buffer_cache", pagesize, 0, 0, 0, 0, 0, 0, 0);
+ if (0 != m_cache)
+ m_bufsiz = pagesize;
}
-
- return flags;
+}
+FileHandle_Impl::Allocator::~Allocator()
+{
+ rtl_cache_destroy (m_cache), m_cache = 0;
}
-#endif
+void FileHandle_Impl::Allocator::allocate (sal_uInt8 ** ppBuffer, size_t * pnSize)
+{
+ OSL_PRECOND((0 != ppBuffer) && (0 != pnSize), "FileHandle_Impl::Allocator::allocate(): contract violation");
+ *ppBuffer = static_cast< sal_uInt8* >(rtl_cache_alloc(m_cache)), *pnSize = m_bufsiz;
+}
+void FileHandle_Impl::Allocator::deallocate (sal_uInt8 * pBuffer)
+{
+ if (0 != pBuffer)
+ rtl_cache_free (m_cache, pBuffer);
+}
+FileHandle_Impl::FileHandle_Impl (int fd, char const * path)
+ : m_strFilePath (0),
+ m_fd (fd),
+ m_state (STATE_SEEKABLE | STATE_READABLE),
+ m_size (0),
+ m_offset (0),
+ m_fileptr (0),
+ m_bufptr (-1),
+ m_buflen (0),
+ m_bufsiz (0),
+ m_buffer (0)
+{
+ rtl_string_newFromStr (&m_strFilePath, path);
+ Allocator::get().allocate (&m_buffer, &m_bufsiz);
+ if (0 != m_buffer)
+ memset (m_buffer, 0, m_bufsiz);
+}
+FileHandle_Impl::~FileHandle_Impl()
+{
+ Allocator::get().deallocate (m_buffer), m_buffer = 0;
+ rtl_string_release (m_strFilePath), m_strFilePath = 0;
+}
-/*******************************************************************
- * osl_openDirectory
- ******************************************************************/
+void* FileHandle_Impl::operator new (size_t n)
+{
+ return rtl_allocateMemory(n);
+}
+void FileHandle_Impl::operator delete (void * p, size_t)
+{
+ rtl_freeMemory(p);
+}
-oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
+size_t FileHandle_Impl::getpagesize()
{
- rtl_uString* ustrSystemPath = NULL;
- oslFileError eRet;
+#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
+ return sal::static_int_cast< size_t >(::getpagesize());
+#else /* POSIX */
+ return sal::static_int_cast< size_t >(::sysconf(_SC_PAGESIZE));
+#endif /* xBSD || POSIX */
+}
- char path[PATH_MAX];
+sal_uInt64 FileHandle_Impl::getPos() const
+{
+ return sal::static_int_cast< sal_uInt64 >(m_fileptr);
+}
- OSL_ASSERT(ustrDirectoryURL && (ustrDirectoryURL->length > 0));
- OSL_ASSERT(pDirectory);
+oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos)
+{
+ OSL_FILE_TRACE("FileHandle_Impl::setPos(%d, %lld) => %lld", m_fd, getPos(), uPos);
+ m_fileptr = sal::static_int_cast< off_t >(uPos);
+ return osl_File_E_None;
+}
- if (0 == ustrDirectoryURL->length )
- return osl_File_E_INVAL;
+sal_uInt64 FileHandle_Impl::getSize() const
+{
+ off_t const bufend = std::max((off_t)(0), m_bufptr) + m_buflen;
+ return std::max(m_size, sal::static_int_cast< sal_uInt64 >(bufend));
+}
- /* convert file URL to system path */
- eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False);
+oslFileError FileHandle_Impl::readAt (
+ off_t nOffset,
+ void * pBuffer,
+ size_t nBytesRequested,
+ sal_uInt64 * pBytesRead)
+{
+ OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::readAt(): not seekable");
+ if (!(m_state & STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
- if( osl_File_E_None != eRet )
- return eRet;
+ OSL_PRECOND((m_state & STATE_READABLE), "FileHandle_Impl::readAt(): not readable");
+ if (!(m_state & STATE_READABLE))
+ return osl_File_E_BADF;
- osl_systemPathRemoveSeparator(ustrSystemPath);
+#if defined(LINUX) || defined(SOLARIS)
- /* convert unicode path to text */
- if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length )
-#ifdef MACOSX
- && macxp_resolveAlias( path, PATH_MAX ) == 0
-#endif /* MACOSX */
- )
+ ssize_t nBytes = ::pread (m_fd, pBuffer, nBytesRequested, nOffset);
+ if ((-1 == nBytes) && (EOVERFLOW == errno))
{
- /* open directory */
- DIR *pdir = opendir( path );
-
- if( pdir )
- {
- /* create and initialize impl structure */
- oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) rtl_allocateMemory( sizeof(oslDirectoryImpl) );
+ /* Some 'pread()'s fail with EOVERFLOW when reading at (or past)
+ * end-of-file, different from 'lseek() + read()' behaviour.
+ * Returning '0 bytes read' and 'osl_File_E_None' instead.
+ */
+ nBytes = 0;
+ }
+ if (-1 == nBytes)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
- if( pDirImpl )
- {
- pDirImpl->pDirStruct = pdir;
- pDirImpl->ustrPath = ustrSystemPath;
+#else /* !(LINUX || SOLARIS) */
- *pDirectory = (oslDirectory) pDirImpl;
- return osl_File_E_None;
- }
- else
- {
- errno = ENOMEM;
- closedir( pdir );
- }
- }
- else
- {
- /* should be removed by optimizer in product version */
- PERROR( "osl_openDirectory", path );
- }
+ if (nOffset != m_offset)
+ {
+ if (-1 == ::lseek (m_fd, nOffset, SEEK_SET))
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+ m_offset = nOffset;
}
- rtl_uString_release( ustrSystemPath );
+ ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested);
+ if (-1 == nBytes)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+ m_offset += nBytes;
- return oslTranslateFileError(OSL_FET_ERROR, errno);
-}
+#endif /* !(LINUX || SOLARIS) */
-/****************************************************************************/
-/* osl_closeDirectory */
-/****************************************************************************/
+ OSL_FILE_TRACE("FileHandle_Impl::readAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
+ *pBytesRead = nBytes;
+ return osl_File_E_None;
+}
-oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
+oslFileError FileHandle_Impl::writeAt (
+ off_t nOffset,
+ void const * pBuffer,
+ size_t nBytesToWrite,
+ sal_uInt64 * pBytesWritten)
{
- oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) Directory;
- oslFileError err = osl_File_E_None;
+ OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::writeAt(): not seekable");
+ if (!(m_state & STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
- OSL_ASSERT( Directory );
+ OSL_PRECOND((m_state & STATE_WRITEABLE), "FileHandle_Impl::writeAt(): not writeable");
+ if (!(m_state & STATE_WRITEABLE))
+ return osl_File_E_BADF;
- if( NULL == pDirImpl )
- return osl_File_E_INVAL;
+#if defined(LINUX) || defined(SOLARIS)
+
+ ssize_t nBytes = ::pwrite (m_fd, pBuffer, nBytesToWrite, nOffset);
+ if (-1 == nBytes)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+
+#else /* !(LINUX || SOLARIS) */
- /* close directory */
- if( closedir( pDirImpl->pDirStruct ) )
+ if (nOffset != m_offset)
{
- err = oslTranslateFileError(OSL_FET_ERROR, errno);
+ if (-1 == ::lseek (m_fd, nOffset, SEEK_SET))
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+ m_offset = nOffset;
}
- /* cleanup members */
- rtl_uString_release( pDirImpl->ustrPath );
+ ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite);
+ if (-1 == nBytes)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+ m_offset += nBytes;
- rtl_freeMemory( pDirImpl );
+#endif /* !(LINUX || SOLARIS) */
- return err;
-}
+ OSL_FILE_TRACE("FileHandle_Impl::writeAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
+ m_size = std::max (m_size, sal::static_int_cast< sal_uInt64 >(nOffset + nBytes));
-/**********************************************
- * osl_readdir_impl_
- *
- * readdir wrapper, filters out "." and ".."
- * on request
- *********************************************/
+ *pBytesWritten = nBytes;
+ return osl_File_E_None;
+}
-static struct dirent* osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
+oslFileError FileHandle_Impl::readFileAt (
+ off_t nOffset,
+ void * pBuffer,
+ size_t nBytesRequested,
+ sal_uInt64 * pBytesRead)
{
- struct dirent* pdirent;
-
- while ((pdirent = readdir(pdir)) != NULL)
+ if (0 == (m_state & STATE_SEEKABLE))
{
- if (bFilterLocalAndParentDir &&
- ((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
- continue;
- else
- break;
+ // not seekable (pipe)
+ ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested);
+ if (-1 == nBytes)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+ *pBytesRead = nBytes;
+ return osl_File_E_None;
+ }
+ else if (0 == m_buffer)
+ {
+ // not buffered
+ return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
}
+ else
+ {
+ sal_uInt8 * buffer = static_cast<sal_uInt8*>(pBuffer);
+ for (*pBytesRead = 0; nBytesRequested > 0; )
+ {
+ off_t const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
+ size_t const bufpos = (nOffset % m_bufsiz);
- return pdirent;
-}
+ if (bufptr != m_bufptr)
+ {
+ // flush current buffer
+ oslFileError result = syncFile();
+ if (result != osl_File_E_None)
+ return (result);
-/****************************************************************************
- * osl_getNextDirectoryItem
- ***************************************************************************/
+ if (nBytesRequested >= m_bufsiz)
+ {
+ // buffer too small, read through from file
+ sal_uInt64 uDone = 0;
+ result = readAt (nOffset, &(buffer[*pBytesRead]), nBytesRequested, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
-oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, sal_uInt32 /*uHint*/)
-{
- oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*)Directory;
- rtl_uString* ustrFileName = NULL;
- rtl_uString* ustrFilePath = NULL;
- struct dirent* pEntry;
+ nBytesRequested -= uDone, *pBytesRead += uDone;
+ return osl_File_E_None;
+ }
- OSL_ASSERT(Directory);
- OSL_ASSERT(pItem);
+ // update buffer (pointer)
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ m_bufptr = bufptr, m_buflen = uDone;
+ }
+ if (bufpos >= m_buflen)
+ {
+ // end of file
+ return osl_File_E_None;
+ }
- if ((NULL == Directory) || (NULL == pItem))
- return osl_File_E_INVAL;
+ size_t const bytes = std::min (m_buflen - bufpos, nBytesRequested);
+ OSL_FILE_TRACE("FileHandle_Impl::readFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
- pEntry = osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
+ memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes);
+ nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes;
+ }
+ return osl_File_E_None;
+ }
+}
- if (NULL == pEntry)
- return osl_File_E_NOENT;
+oslFileError FileHandle_Impl::writeFileAt (
+ off_t nOffset,
+ void const * pBuffer,
+ size_t nBytesToWrite,
+ sal_uInt64 * pBytesWritten)
+{
+ if (0 == (m_state & STATE_SEEKABLE))
+ {
+ // not seekable (pipe)
+ ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite);
+ if (-1 == nBytes)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+ *pBytesWritten = nBytes;
+ return osl_File_E_None;
+ }
+ else if (0 == m_buffer)
+ {
+ // not buffered
+ return writeAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten);
+ }
+ else
+ {
+ sal_uInt8 const * buffer = static_cast<sal_uInt8 const *>(pBuffer);
+ for (*pBytesWritten = 0; nBytesToWrite > 0; )
+ {
+ off_t const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
+ size_t const bufpos = (nOffset % m_bufsiz);
+ if (bufptr != m_bufptr)
+ {
+ // flush current buffer
+ oslFileError result = syncFile();
+ if (result != osl_File_E_None)
+ return (result);
+ if (nBytesToWrite >= m_bufsiz)
+ {
+ // buffer to small, write through to file
+ sal_uInt64 uDone = 0;
+ result = writeAt (nOffset, &(buffer[*pBytesWritten]), nBytesToWrite, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ if (uDone != nBytesToWrite)
+ return osl_File_E_IO;
+
+ nBytesToWrite -= uDone, *pBytesWritten += uDone;
+ return osl_File_E_None;
+ }
-#if defined(MACOSX)
+ // update buffer (pointer)
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ m_bufptr = bufptr, m_buflen = uDone;
+ }
- // convert decomposed filename to precomposed unicode
- char composed_name[BUFSIZ];
- CFMutableStringRef strRef = CFStringCreateMutable (NULL, 0 );
- CFStringAppendCString( strRef, pEntry->d_name, kCFStringEncodingUTF8 ); //UTF8 is default on Mac OSX
- CFStringNormalize( strRef, kCFStringNormalizationFormC );
- CFStringGetCString( strRef, composed_name, BUFSIZ, kCFStringEncodingUTF8 );
- CFRelease( strRef );
- rtl_string2UString( &ustrFileName, composed_name, strlen( composed_name),
- osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
-
-#else // not MACOSX
- /* convert file name to unicode */
- rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
- osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
- OSL_ASSERT(ustrFileName != 0);
+ size_t const bytes = std::min (m_bufsiz - bufpos, nBytesToWrite);
+ OSL_FILE_TRACE("FileHandle_Impl::writeFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
-#endif
+ memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes);
+ nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes;
- osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &ustrFilePath);
- rtl_uString_release( ustrFileName );
+ m_buflen = std::max(m_buflen, bufpos + bytes);
+ m_state |= STATE_MODIFIED;
+ }
+ return osl_File_E_None;
+ }
+}
-#ifdef _DIRENT_HAVE_D_TYPE
- if(*pItem)
- oslDirectoryItemImpl_release( ( oslDirectoryItemImpl* )( *pItem ) );
+oslFileError FileHandle_Impl::readLineAt (
+ off_t nOffset,
+ sal_Sequence ** ppSequence,
+ sal_uInt64 * pBytesRead)
+{
+ oslFileError result = osl_File_E_None;
- *pItem = (oslDirectoryItem) oslDirectoryItemImpl_CreateNew( ustrFilePath, true, pEntry->d_type );
-#else
- /* use path as directory item */
- *pItem = (oslDirectoryItem) ustrFilePath;
-#endif
+ off_t bufptr = nOffset / m_bufsiz * m_bufsiz;
+ if (bufptr != m_bufptr)
+ {
+ /* flush current buffer */
+ result = syncFile();
+ if (result != osl_File_E_None)
+ return (result);
- return osl_File_E_None;
-}
+ /* update buffer (pointer) */
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
-/****************************************************************************/
-/* osl_getDirectoryItem */
-/****************************************************************************/
+ m_bufptr = bufptr, m_buflen = uDone;
+ }
-oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
-{
- rtl_uString* ustrSystemPath = NULL;
- oslFileError osl_error = osl_File_E_INVAL;
+ static int const LINE_STATE_BEGIN = 0;
+ static int const LINE_STATE_CR = 1;
+ static int const LINE_STATE_LF = 2;
- OSL_ASSERT(ustrFileURL);
- OSL_ASSERT(pItem);
+ size_t bufpos = nOffset - m_bufptr, curpos = bufpos, dstpos = 0;
+ int state = (bufpos >= m_buflen) ? LINE_STATE_LF : LINE_STATE_BEGIN;
- if (0 == ustrFileURL->length || NULL == pItem)
- return osl_File_E_INVAL;
+ for ( ; state != LINE_STATE_LF; )
+ {
+ if (curpos >= m_buflen)
+ {
+ /* buffer examined */
+ if (0 < (curpos - bufpos))
+ {
+ /* flush buffer to sequence */
+ result = writeSequence_Impl (
+ ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos);
+ if (result != osl_File_E_None)
+ return (result);
+ *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
+ }
- osl_error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &ustrSystemPath, sal_False);
+ bufptr = nOffset / m_bufsiz * m_bufsiz;
+ if (bufptr != m_bufptr)
+ {
+ /* update buffer (pointer) */
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ m_bufptr = bufptr, m_buflen = uDone;
+ }
- if (osl_File_E_None != osl_error)
- return osl_error;
+ bufpos = nOffset - m_bufptr, curpos = bufpos;
+ if (bufpos >= m_buflen)
+ break;
+ }
+ switch (state)
+ {
+ case LINE_STATE_CR:
+ state = LINE_STATE_LF;
+ switch (m_buffer[curpos])
+ {
+ case 0x0A: /* CRLF */
+ /* eat current char */
+ curpos++;
+ break;
+ default: /* single CR */
+ /* keep current char */
+ break;
+ }
+ break;
+ default:
+ /* determine next state */
+ switch (m_buffer[curpos])
+ {
+ case 0x0A: /* single LF */
+ state = LINE_STATE_LF;
+ break;
+ case 0x0D: /* CR */
+ state = LINE_STATE_CR;
+ break;
+ default: /* advance to next char */
+ curpos++;
+ break;
+ }
+ if (state != LINE_STATE_BEGIN)
+ {
+ /* store (and eat) the newline char */
+ m_buffer[curpos] = 0x0A, curpos++;
+
+ /* flush buffer to sequence */
+ result = writeSequence_Impl (
+ ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos - 1);
+ if (result != osl_File_E_None)
+ return (result);
+ *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
+ }
+ break;
+ }
+ }
- osl_systemPathRemoveSeparator(ustrSystemPath);
+ result = writeSequence_Impl (ppSequence, &dstpos, 0, 0);
+ if (result != osl_File_E_None)
+ return (result);
+ if (0 < dstpos)
+ return osl_File_E_None;
+ if (bufpos >= m_buflen)
+ return osl_File_E_AGAIN;
+ return osl_File_E_None;
+}
- if (0 == access_u(ustrSystemPath, F_OK))
+oslFileError FileHandle_Impl::writeSequence_Impl (
+ sal_Sequence ** ppSequence,
+ size_t * pnOffset,
+ const void * pBuffer,
+ size_t nBytes)
+{
+ sal_Int32 nElements = *pnOffset + nBytes;
+ if (!*ppSequence)
{
-#ifdef _DIRENT_HAVE_D_TYPE
- *pItem = (oslDirectoryItem) oslDirectoryItemImpl_CreateNew( ustrSystemPath, false );
-#else
- *pItem = (oslDirectoryItem)ustrSystemPath;
-#endif
- osl_error = osl_File_E_None;
+ /* construct sequence */
+ rtl_byte_sequence_constructNoDefault(ppSequence, nElements);
}
- else
+ else if (nElements != (*ppSequence)->nElements)
{
- osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
- rtl_uString_release(ustrSystemPath);
+ /* resize sequence */
+ rtl_byte_sequence_realloc(ppSequence, nElements);
}
- return osl_error;
+ if (*ppSequence != 0)
+ {
+ /* fill sequence */
+ memcpy(&((*ppSequence)->elements[*pnOffset]), pBuffer, nBytes), *pnOffset += nBytes;
+ }
+ return (*ppSequence != 0) ? osl_File_E_None : osl_File_E_NOMEM;
}
+oslFileError FileHandle_Impl::syncFile()
+{
+ oslFileError result = osl_File_E_None;
+ if (m_state & STATE_MODIFIED)
+ {
+ sal_uInt64 uDone = 0;
+ result = writeAt (m_bufptr, m_buffer, m_buflen, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ if (uDone != m_buflen)
+ return osl_File_E_IO;
+ m_state &= ~STATE_MODIFIED;
+ }
+ return (result);
+}
-/****************************************************************************/
-/* osl_acquireDirectoryItem */
-/****************************************************************************/
-
-oslFileError osl_acquireDirectoryItem( oslDirectoryItem Item )
+/****************************************************************************
+ * osl_createFileHandleFromFD
+ ***************************************************************************/
+extern "C" oslFileHandle osl_createFileHandleFromFD( int fd )
{
-#ifdef _DIRENT_HAVE_D_TYPE
- oslDirectoryItemImpl* pImpl = (oslDirectoryItemImpl*) Item;
-#else
- rtl_uString* ustrFilePath = (rtl_uString *) Item;
-#endif
+ if (-1 == fd)
+ return 0; // EINVAL
- OSL_ASSERT( Item );
+ struct stat aFileStat;
+ if (-1 == fstat (fd, &aFileStat))
+ return 0; // EBADF
-#ifdef _DIRENT_HAVE_D_TYPE
- if( pImpl )
- oslDirectoryItemImpl_acquire( pImpl );
-#else
- if( ustrFilePath )
- rtl_uString_acquire( ustrFilePath );
-#endif
+ FileHandle_Impl * pImpl = new FileHandle_Impl (fd);
+ if (0 == pImpl)
+ return 0; // ENOMEM
- return osl_File_E_None;
-}
+ // assume writeable
+ pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE;
+ if (!S_ISREG(aFileStat.st_mode))
+ {
+ /* not a regular file, mark not seekable */
+ pImpl->m_state &= ~FileHandle_Impl::STATE_SEEKABLE;
+ }
+ else
+ {
+ /* regular file, init current size */
+ pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
+ }
-/****************************************************************************/
-/* osl_releaseDirectoryItem */
-/****************************************************************************/
+ OSL_FILE_TRACE("osl_createFileHandleFromFD(%d, writeable) => %s",
+ pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath));
+ return (oslFileHandle)(pImpl);
+}
-oslFileError osl_releaseDirectoryItem( oslDirectoryItem Item )
+/*******************************************************************
+ * osl_file_adjustLockFlags
+ ******************************************************************/
+static int osl_file_adjustLockFlags (const char * path, int flags)
{
-#ifdef _DIRENT_HAVE_D_TYPE
- oslDirectoryItemImpl* pImpl = (oslDirectoryItemImpl*) Item;
-#else
- rtl_uString* ustrFilePath = (rtl_uString *) Item;
-#endif
-
- OSL_ASSERT( Item );
-
-#ifdef _DIRENT_HAVE_D_TYPE
- if( pImpl )
- oslDirectoryItemImpl_release( pImpl );
-#else
- if( ustrFilePath )
- rtl_uString_release( ustrFilePath );
-#endif
+#ifdef MACOSX
+ /*
+ * The AFP implementation of MacOS X 10.4 treats O_EXLOCK in a way
+ * that makes it impossible for OOo to create a backup copy of the
+ * file it keeps opened. OTOH O_SHLOCK for AFP behaves as desired by
+ * the OOo file handling, so we need to check the path of the file
+ * for the filesystem name.
+ */
+ struct statfs s;
+ if( 0 <= statfs( path, &s ) )
+ {
+ if( 0 == strncmp("afpfs", s.f_fstypename, 5) )
+ {
+ flags &= ~O_EXLOCK;
+ flags |= O_SHLOCK;
+ }
+ else
+ {
+ /* Needed flags to allow opening a webdav file */
+ flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
+ }
+ }
+#endif /* MACOSX */
- return osl_File_E_None;
+ (void) path;
+ return flags;
}
/****************************************************************************
- * osl_createFileHandleFromFD
+ * osl_file_queryLocking
***************************************************************************/
-
-oslFileHandle osl_createFileHandleFromFD( int fd )
+struct Locking_Impl
{
- oslFileHandleImpl* pHandleImpl = NULL;
-
- if ( fd >= 0 )
+ int m_enabled;
+ Locking_Impl() : m_enabled(0)
{
- pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
-
- if( pHandleImpl )
+#ifndef HAVE_O_EXLOCK
+ m_enabled = ((getenv("SAL_ENABLE_FILE_LOCKING") != 0) || (getenv("STAR_ENABLE_FILE_LOCKING") != 0));
+#endif /* HAVE_O_EXLOCK */
+ }
+};
+static int osl_file_queryLocking (sal_uInt32 uFlags)
+{
+ if (!(uFlags & osl_File_OpenFlag_NoLock))
+ {
+ if ((uFlags & osl_File_OpenFlag_Write) || (uFlags & osl_File_OpenFlag_Create))
{
- pHandleImpl->ustrFilePath = NULL;
- rtl_uString_new( &pHandleImpl->ustrFilePath );
- pHandleImpl->fd = fd;
-
- /* FIXME: it should be detected whether the file has been locked */
- pHandleImpl->bLocked = sal_True;
+ static Locking_Impl g_locking;
+ return (g_locking.m_enabled != 0);
}
}
-
- return (oslFileHandle)pHandleImpl;
+ return 0;
}
-
/****************************************************************************
* osl_openFile
***************************************************************************/
-
#ifdef HAVE_O_EXLOCK
#define OPEN_WRITE_FLAGS ( O_RDWR | O_EXLOCK | O_NONBLOCK )
#define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR | O_EXLOCK | O_NONBLOCK )
@@ -645,593 +763,188 @@ oslFileHandle osl_createFileHandleFromFD( int fd )
#define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR )
#endif
-oslFileError osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
+oslFileError
+SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
{
- oslFileHandleImpl* pHandleImpl = NULL;
oslFileError eRet;
- rtl_uString* ustrFilePath = NULL;
-
- char buffer[PATH_MAX];
- int fd;
- int mode = S_IRUSR | S_IRGRP | S_IROTH;
- int flags = O_RDONLY;
-
- struct flock aflock;
-
- /* locking the complete file */
- aflock.l_type = 0;
- aflock.l_whence = SEEK_SET;
- aflock.l_start = 0;
- aflock.l_len = 0;
- OSL_ASSERT( ustrFileURL );
- OSL_ASSERT( pHandle );
-
- if( ( 0 == ustrFileURL->length ) )
+ if ((ustrFileURL == 0) || (ustrFileURL->length == 0) || (pHandle == 0))
return osl_File_E_INVAL;
/* convert file URL to system path */
- eRet = osl_getSystemPathFromFileURL( ustrFileURL, &ustrFilePath );
-
- if( osl_File_E_None != eRet )
+ char buffer[PATH_MAX];
+ eRet = FileURLToPath (buffer, sizeof(buffer), ustrFileURL);
+ if (eRet != osl_File_E_None)
return eRet;
-
- osl_systemPathRemoveSeparator(ustrFilePath);
-
- /* convert unicode path to text */
- if( UnicodeToText( buffer, PATH_MAX, ustrFilePath->buffer, ustrFilePath->length )
#ifdef MACOSX
- && macxp_resolveAlias( buffer, PATH_MAX ) == 0
+ if (macxp_resolveAlias (buffer, sizeof(buffer)) != 0)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
#endif /* MACOSX */
- )
+
+ /* set mode and flags */
+ int mode = S_IRUSR | S_IRGRP | S_IROTH;
+ int flags = O_RDONLY;
+ if (uFlags & osl_File_OpenFlag_Write)
{
- /* we do not open devices or such here */
- if( !( uFlags & osl_File_OpenFlag_Create ) )
- {
- struct stat aFileStat;
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ flags = OPEN_WRITE_FLAGS;
+ }
+ if (uFlags & osl_File_OpenFlag_Create)
+ {
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ flags = OPEN_CREATE_FLAGS;
+ }
+ if (uFlags & osl_File_OpenFlag_NoLock)
+ {
+#ifdef HAVE_O_EXLOCK
+ flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
+#endif /* HAVE_O_EXLOCK */
+ }
+ else
+ {
+ flags = osl_file_adjustLockFlags (buffer, flags);
+ }
- if( 0 > stat( buffer, &aFileStat ) )
- {
- PERROR( "osl_openFile", buffer );
- eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
- }
+ /* open the file */
+ int fd = open( buffer, flags, mode );
+ if (-1 == fd)
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
- else if( !S_ISREG( aFileStat.st_mode ) )
- {
- eRet = osl_File_E_INVAL;
- }
+ /* reset O_NONBLOCK flag */
+ if (flags & O_NONBLOCK)
+ {
+ int f = fcntl (fd, F_GETFL, 0);
+ if (-1 == f)
+ {
+ eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
+ (void) close(fd);
+ return eRet;
}
-
- if( osl_File_E_None == eRet )
+ if (-1 == fcntl (fd, F_SETFL, (f & ~O_NONBLOCK)))
{
- /*
- * set flags and mode
- */
-
- if ( uFlags & osl_File_OpenFlag_Write )
- {
- mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- flags = OPEN_WRITE_FLAGS;
-#ifdef MACOSX
- flags = adjustLockFlags(buffer, flags);
-#endif
- aflock.l_type = F_WRLCK;
- }
+ eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
+ (void) close(fd);
+ return eRet;
+ }
+ }
- if ( uFlags & osl_File_OpenFlag_Create )
- {
- mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- flags = OPEN_CREATE_FLAGS;
-#ifdef MACOSX
- flags = adjustLockFlags(buffer, flags);
-#endif
- }
+ /* get file status (mode, size) */
+ struct stat aFileStat;
+ if (-1 == fstat (fd, &aFileStat))
+ {
+ eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
+ (void) close(fd);
+ return eRet;
+ }
+ if (!S_ISREG(aFileStat.st_mode))
+ {
+ /* we only open regular files here */
+ (void) close(fd);
+ return osl_File_E_INVAL;
+ }
- sal_Bool bNeedsLock = ( ( uFlags & osl_File_OpenFlag_NoLock ) == 0 );
- if ( !bNeedsLock )
- {
+ if (osl_file_queryLocking (uFlags))
+ {
#ifdef MACOSX
- flags &= ~O_EXLOCK;
- flags &= ~O_SHLOCK;
-#endif
- }
-
- /* open the file */
- fd = open( buffer, flags, mode );
- if ( fd >= 0 )
+ if (-1 == flock (fd, LOCK_EX | LOCK_NB))
+ {
+ /* Mac OSX returns ENOTSUP for webdav drives. We should try read lock */
+ if ((errno != ENOTSUP) || ((-1 == flock (fd, LOCK_SH | LOCK_NB)) && (errno != ENOTSUP)))
{
- sal_Bool bLocked = sal_False;
- if( bNeedsLock )
- {
-#ifndef HAVE_O_EXLOCK
- /* check if file lock is enabled and clear l_type member of flock otherwise */
- if( (char *) -1 == pFileLockEnvVar )
- {
- /* FIXME: this is not MT safe */
- pFileLockEnvVar = getenv("SAL_ENABLE_FILE_LOCKING");
-
- if( NULL == pFileLockEnvVar)
- pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING");
- }
-#else
- /* disable range based locking */
- pFileLockEnvVar = NULL;
-
- /* remove the NONBLOCK flag again */
- flags = fcntl(fd, F_GETFL, NULL);
- flags &= ~O_NONBLOCK;
- if( 0 > fcntl(fd, F_SETFL, flags) )
- {
- close(fd);
- return oslTranslateFileError(OSL_FET_ERROR, errno);
- }
-#endif
- if( NULL == pFileLockEnvVar )
- aflock.l_type = 0;
-
- /* lock the file if flock.l_type is set */
-#ifdef MACOSX
- bLocked = ( F_WRLCK != aflock.l_type );
- if (!bLocked)
- {
- /* Mac OSX returns ENOTSUP for webdav drives. We should try read lock */
- if ( 0 == flock( fd, LOCK_EX | LOCK_NB ) || errno == ENOTSUP )
- bLocked = ( errno != ENOTSUP ) || ( 0 == flock( fd, LOCK_SH | LOCK_NB ) || errno == ENOTSUP );
- }
-#else /* MACOSX */
- bLocked = ( F_WRLCK != aflock.l_type || -1 != fcntl( fd, F_SETLK, &aflock ) );
-#endif /* MACOSX */
-
- }
-
- if ( !bNeedsLock || bLocked )
- {
- /* allocate memory for impl structure */
- pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
- if( pHandleImpl )
- {
- pHandleImpl->ustrFilePath = ustrFilePath;
- pHandleImpl->fd = fd;
- pHandleImpl->bLocked = bLocked;
-
- *pHandle = (oslFileHandle) pHandleImpl;
-
- return osl_File_E_None;
- }
- else
- {
- errno = ENOMEM;
- }
- }
-
- close( fd );
+ eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
+ (void) close(fd);
+ return eRet;
}
-
- PERROR( "osl_openFile", buffer );
- eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
}
- }
- else
- eRet = osl_File_E_INVAL;
-
- rtl_uString_release( ustrFilePath );
- return eRet;
-}
-
-/****************************************************************************/
-/* osl_closeFile */
-/****************************************************************************/
-
-oslFileError osl_closeFile( oslFileHandle Handle )
-{
- oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
- oslFileError eRet = osl_File_E_INVAL;
-
- OSL_ASSERT( Handle );
-
- if( pHandleImpl )
- {
- rtl_uString_release( pHandleImpl->ustrFilePath );
-
- /* release file lock if locking is enabled */
- if( pFileLockEnvVar )
+#else /* F_SETLK */
{
struct flock aflock;
- aflock.l_type = F_UNLCK;
+ aflock.l_type = F_WRLCK;
aflock.l_whence = SEEK_SET;
aflock.l_start = 0;
aflock.l_len = 0;
- if ( pHandleImpl->bLocked )
+ if (-1 == fcntl (fd, F_SETLK, &aflock))
{
- /* FIXME: check if file is really locked ? */
-
- /* release the file share lock on this file */
-#ifdef MACOSX
- /* Mac OSX will return ENOTSUP for webdav drives. We should ignore the error */
- if ( 0 != flock( pHandleImpl->fd, LOCK_UN | LOCK_NB ) && errno != ENOTSUP )
-#else /* MACOSX */
- if( -1 == fcntl( pHandleImpl->fd, F_SETLK, &aflock ) )
-#endif /* MACOSX */
- {
- PERROR( "osl_closeFile", "unlock failed" );
- }
+ eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
+ (void) close(fd);
+ return eRet;
}
}
-
- if( 0 > close( pHandleImpl->fd ) )
- {
- eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
- }
- else
- eRet = osl_File_E_None;
-
- rtl_freeMemory( pHandleImpl );
+#endif /* F_SETLK */
}
- return eRet;
-}
-
-/****************************************************************************/
-/* osl_isEndOfFile */
-/****************************************************************************/
-
-oslFileError SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
-{
- oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
- oslFileError eRet = osl_File_E_INVAL;
-
- if ( pHandleImpl)
+ /* allocate memory for impl structure */
+ FileHandle_Impl * pImpl = new FileHandle_Impl (fd, buffer);
+ if (!pImpl)
{
- long curPos = lseek( pHandleImpl->fd, 0, SEEK_CUR );
-
- if ( curPos >= 0 )
- {
- long endPos = lseek( pHandleImpl->fd, 0, SEEK_END );
-
- if ( endPos >= 0 )
- {
- *pIsEOF = ( curPos == endPos );
- curPos = lseek( pHandleImpl->fd, curPos, SEEK_SET );
-
- if ( curPos >= 0 )
- eRet = osl_File_E_None;
- else
- eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
- }
- else
- eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
- }
- else
- eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
- }
-
- return eRet;
-}
-
-
-/****************************************************************************/
-/* osl_moveFile */
-/****************************************************************************/
-
-oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
-{
- char srcPath[PATH_MAX];
- char destPath[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrFileURL );
- OSL_ASSERT( ustrDestURL );
-
- /* convert source url to system path */
- eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
- /* convert destination url to system path */
- eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
-#ifdef MACOSX
- if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
-
- return oslDoMoveFile( srcPath, destPath );
-}
-
-/****************************************************************************/
-/* osl_copyFile */
-/****************************************************************************/
-
-oslFileError osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
-{
- char srcPath[PATH_MAX];
- char destPath[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrFileURL );
- OSL_ASSERT( ustrDestURL );
-
- /* convert source url to system path */
- eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
- /* convert destination url to system path */
- eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
-#ifdef MACOSX
- if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
-
- return osl_psz_copyFile( srcPath, destPath );
-}
-
-/****************************************************************************/
-/* osl_removeFile */
-/****************************************************************************/
-
-oslFileError osl_removeFile( rtl_uString* ustrFileURL )
-{
- char path[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrFileURL );
-
- /* convert file url to system path */
- eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
-#ifdef MACOSX
- if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
-
- return osl_psz_removeFile( path );
-}
-
-/****************************************************************************/
-/* osl_getVolumeInformation */
-/****************************************************************************/
-
-oslFileError osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
-{
- char path[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrDirectoryURL );
- OSL_ASSERT( pInfo );
-
- /* convert directory url to system path */
- eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
-#ifdef MACOSX
- if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
-
- return osl_psz_getVolumeInformation( path, pInfo, uFieldMask);
-}
-
-/****************************************************************************/
-/* osl_createDirectory */
-/****************************************************************************/
-
-oslFileError osl_createDirectory( rtl_uString* ustrDirectoryURL )
-{
- char path[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrDirectoryURL );
-
- /* convert directory url to system path */
- eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
- if( eRet != osl_File_E_None )
+ eRet = oslTranslateFileError (OSL_FET_ERROR, ENOMEM);
+ (void) close(fd);
return eRet;
+ }
+ if (flags & O_RDWR)
+ pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE;
+ pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
-#ifdef MACOSX
- if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
+ OSL_TRACE("osl_openFile(%d, %s) => %s", pImpl->m_fd,
+ flags & O_RDWR ? "writeable":"readonly",
+ rtl_string_getStr(pImpl->m_strFilePath));
- return osl_psz_createDirectory( path );
+ *pHandle = (oslFileHandle)(pImpl);
+ return osl_File_E_None;
}
/****************************************************************************/
-/* osl_removeDirectory */
+/* osl_closeFile */
/****************************************************************************/
-
-oslFileError osl_removeDirectory( rtl_uString* ustrDirectoryURL )
+oslFileError
+SAL_CALL osl_closeFile( oslFileHandle Handle )
{
- char path[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrDirectoryURL );
-
- /* convert directory url to system path */
- eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
-#ifdef MACOSX
- if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- return osl_psz_removeDirectory( path );
-}
+ if ((pImpl == 0) || (pImpl->m_fd < 0))
+ return osl_File_E_INVAL;
-//#############################################
-int path_make_parent(sal_Unicode* path)
-{
- int i = rtl_ustr_lastIndexOfChar(path, '/');
-
- if (i > 0)
+ /* close(2) implicitly (and unconditionally) unlocks */
+ OSL_TRACE("osl_closeFile(%d) => %s", pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath));
+ oslFileError result = pImpl->syncFile();
+ if (result != osl_File_E_None)
{
- *(path + i) = 0;
- return i;
+ /* close, ignoring double failure */
+ (void) close (pImpl->m_fd);
}
- else
- return 0;
-}
-
-//#############################################
-int create_dir_with_callback(
- sal_Unicode* directory_path,
- oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
- void* pData)
-{
- int mode = S_IRWXU | S_IRWXG | S_IRWXO;
-
- if (osl::mkdir(directory_path, mode) == 0)
+ else if (-1 == close (pImpl->m_fd))
{
- if (aDirectoryCreationCallbackFunc)
- {
- rtl::OUString url;
- osl::FileBase::getFileURLFromSystemPath(directory_path, url);
- aDirectoryCreationCallbackFunc(pData, url.pData);
- }
- return 0;
+ /* translate error code */
+ result = oslTranslateFileError (OSL_FET_ERROR, errno);
}
- return errno;
-}
-//#############################################
-oslFileError create_dir_recursively_(
- sal_Unicode* dir_path,
- oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
- void* pData)
-{
- OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \
- "Path must not end with a slash");
-
- int native_err = create_dir_with_callback(
- dir_path, aDirectoryCreationCallbackFunc, pData);
-
- if (native_err == 0)
- return osl_File_E_None;
-
- if (native_err != ENOENT)
- return oslTranslateFileError(OSL_FET_ERROR, native_err);
-
- // we step back until '/a_dir' at maximum because
- // we should get an error unequal ENOENT when
- // we try to create 'a_dir' at '/' and would so
- // return before
- int pos = path_make_parent(dir_path);
-
- oslFileError osl_error = create_dir_recursively_(
- dir_path, aDirectoryCreationCallbackFunc, pData);
-
- if (osl_File_E_None != osl_error)
- return osl_error;
-
- dir_path[pos] = '/';
-
- return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
+ delete pImpl;
+ return (result);
}
-//#######################################
-oslFileError SAL_CALL osl_createDirectoryPath(
- rtl_uString* aDirectoryUrl,
- oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
- void* pData)
+/************************************************
+ * osl_syncFile
+ ***********************************************/
+oslFileError
+SAL_CALL osl_syncFile(oslFileHandle Handle)
{
- if (aDirectoryUrl == NULL)
- return osl_File_E_INVAL;
-
- rtl::OUString sys_path;
- oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
- aDirectoryUrl, &sys_path.pData, sal_False);
-
- if (osl_error != osl_File_E_None)
- return osl_error;
-
- osl::systemPathRemoveSeparator(sys_path);
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- // const_cast because sys_path is a local copy which we want to modify inplace instead of
- // coyp it into another buffer on the heap again
- return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
-}
-
-/****************************************************************************/
-/* osl_getCanonicalName */
-/****************************************************************************/
-
-oslFileError osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
-{
- OSL_ENSURE(sal_False, "osl_getCanonicalName not implemented");
+ if ((0 == pImpl) || (-1 == pImpl->m_fd))
+ return osl_File_E_INVAL;
- rtl_uString_newFromString(pustrValidURL, ustrFileURL);
+ OSL_FILE_TRACE("osl_syncFile(%d)", pImpl->m_fd);
+ oslFileError result = pImpl->syncFile();
+ if (result != osl_File_E_None)
+ return (result);
+ if (-1 == fsync (pImpl->m_fd))
+ return oslTranslateFileError (OSL_FET_ERROR, errno);
+
return osl_File_E_None;
}
-
-/****************************************************************************/
-/* osl_setFileAttributes */
-/****************************************************************************/
-
-oslFileError osl_setFileAttributes( rtl_uString* ustrFileURL, sal_uInt64 uAttributes )
-{
- char path[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrFileURL );
-
- /* convert file url to system path */
- eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
-#ifdef MACOSX
- if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
-
- return osl_psz_setFileAttributes( path, uAttributes );
-}
-
-/****************************************************************************/
-/* osl_setFileTime */
-/****************************************************************************/
-
-oslFileError osl_setFileTime( rtl_uString* ustrFileURL, const TimeValue* pCreationTime,
- const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime )
-{
- char path[PATH_MAX];
- oslFileError eRet;
-
- OSL_ASSERT( ustrFileURL );
-
- /* convert file url to system path */
- eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
- if( eRet != osl_File_E_None )
- return eRet;
-
-#ifdef MACOSX
- if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
- return oslTranslateFileError( OSL_FET_ERROR, errno );
-#endif/* MACOSX */
-
- return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
-}
-
-/******************************************************************************
- *
- * Exported Module Functions
- * (independent of C or Unicode Strings)
- *
- *****************************************************************************/
-
/*******************************************
osl_mapFile
********************************************/
@@ -1244,9 +957,9 @@ SAL_CALL osl_mapFile (
sal_uInt32 uFlags
)
{
- oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pHandleImpl) || (-1 == pHandleImpl->fd) || (0 == ppAddr))
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppAddr))
return osl_File_E_INVAL;
*ppAddr = 0;
@@ -1260,7 +973,7 @@ SAL_CALL osl_mapFile (
return osl_File_E_OVERFLOW;
off_t const nOffset = sal::static_int_cast< off_t >(uOffset);
- void* p = mmap(NULL, nLength, PROT_READ, MAP_SHARED, pHandleImpl->fd, nOffset);
+ void* p = mmap(NULL, nLength, PROT_READ, MAP_SHARED, pImpl->m_fd, nOffset);
if (MAP_FAILED == p)
return oslTranslateFileError(OSL_FET_ERROR, errno);
*ppAddr = p;
@@ -1268,11 +981,7 @@ SAL_CALL osl_mapFile (
if (uFlags & osl_File_MapFlag_RandomAccess)
{
// Determine memory pagesize.
-#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
- size_t const nPageSize = getpagesize();
-#else /* POSIX */
- size_t const nPageSize = sysconf(_SC_PAGESIZE);
-#endif /* xBSD || POSIX */
+ size_t const nPageSize = FileHandle_Impl::getpagesize();
if (size_t(-1) != nPageSize)
{
/*
@@ -1321,64 +1030,83 @@ SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength)
}
/*******************************************
- osl_readFile
+ osl_readLine
********************************************/
-
-oslFileError osl_readFile(oslFileHandle Handle, void* pBuffer, sal_uInt64 uBytesRequested, sal_uInt64* pBytesRead)
+oslFileError
+SAL_CALL osl_readLine (
+ oslFileHandle Handle,
+ sal_Sequence ** ppSequence)
{
- ssize_t nBytes = 0;
- oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead))
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppSequence))
return osl_File_E_INVAL;
-
- nBytes = read(
- pHandleImpl->fd, pBuffer,
- ((uBytesRequested
- <= static_cast< size_t >(std::numeric_limits< ssize_t >::max()))
- ? static_cast< size_t >(uBytesRequested)
- : static_cast< size_t >(std::numeric_limits< ssize_t >::max())));
+ sal_uInt64 uBytesRead = 0;
- if (-1 == nBytes)
- return oslTranslateFileError(OSL_FET_ERROR, errno);
-
- *pBytesRead = nBytes;
- return osl_File_E_None;
+ // read at current fileptr; fileptr += uBytesRead;
+ oslFileError result = pImpl->readLineAt (
+ pImpl->m_fileptr, ppSequence, &uBytesRead);
+ if (result == osl_File_E_None)
+ pImpl->m_fileptr += uBytesRead;
+ return (result);
}
/*******************************************
- osl_writeFile
+ osl_readFile
********************************************/
-
-oslFileError osl_writeFile(oslFileHandle Handle, const void* pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64* pBytesWritten)
+oslFileError
+SAL_CALL osl_readFile (
+ oslFileHandle Handle,
+ void * pBuffer,
+ sal_uInt64 uBytesRequested,
+ sal_uInt64 * pBytesRead)
{
- ssize_t nBytes = 0;
- oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- OSL_ASSERT(pHandleImpl);
- OSL_ASSERT(pBuffer);
- OSL_ASSERT(pBytesWritten);
-
- if ((0 == pHandleImpl) || (0 == pBuffer) || (0 == pBytesWritten))
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
return osl_File_E_INVAL;
+
+ static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
+ if (g_limit_ssize_t < uBytesRequested)
+ return osl_File_E_OVERFLOW;
+ size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested);
- OSL_ASSERT(pHandleImpl->fd >= 0);
+ // read at current fileptr; fileptr += *pBytesRead;
+ oslFileError result = pImpl->readFileAt (
+ pImpl->m_fileptr, pBuffer, nBytesRequested, pBytesRead);
+ if (result == osl_File_E_None)
+ pImpl->m_fileptr += *pBytesRead;
+ return (result);
+}
- if (pHandleImpl->fd < 0)
- return osl_File_E_INVAL;
+/*******************************************
+ osl_writeFile
+********************************************/
+oslFileError
+SAL_CALL osl_writeFile (
+ oslFileHandle Handle,
+ const void * pBuffer,
+ sal_uInt64 uBytesToWrite,
+ sal_uInt64 * pBytesWritten)
+{
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- nBytes = write(
- pHandleImpl->fd, pBuffer,
- ((uBytesToWrite
- <= static_cast< size_t >(std::numeric_limits< ssize_t >::max()))
- ? static_cast< size_t >(uBytesToWrite)
- : static_cast< size_t >(std::numeric_limits< ssize_t >::max())));
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten))
+ return osl_File_E_INVAL;
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
+ return osl_File_E_BADF;
- if (-1 == nBytes)
- return oslTranslateFileError(OSL_FET_ERROR, errno);
+ static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
+ if (g_limit_ssize_t < uBytesToWrite)
+ return osl_File_E_OVERFLOW;
+ size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite);
- *pBytesWritten = nBytes;
- return osl_File_E_None;
+ // write at current fileptr; fileptr += *pBytesWritten;
+ oslFileError result = pImpl->writeFileAt (
+ pImpl->m_fileptr, pBuffer, nBytesToWrite, pBytesWritten);
+ if (result == osl_File_E_None)
+ pImpl->m_fileptr += *pBytesWritten;
+ return (result);
}
/*******************************************
@@ -1392,10 +1120,12 @@ SAL_CALL osl_readFileAt (
sal_uInt64 uBytesRequested,
sal_uInt64* pBytesRead)
{
- oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead))
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
return osl_File_E_INVAL;
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
if (g_limit_off_t < uOffset)
@@ -1407,35 +1137,8 @@ SAL_CALL osl_readFileAt (
return osl_File_E_OVERFLOW;
size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested);
-#if defined(LINUX) || defined(SOLARIS)
-
- ssize_t nBytes = ::pread(pHandleImpl->fd, pBuffer, nBytesRequested, nOffset);
- if ((-1 == nBytes) && (EOVERFLOW == errno))
- {
- /*
- * Workaround for 'pread()' failure at end-of-file:
- *
- * Some 'pread()'s fail with EOVERFLOW when reading at (or past)
- * end-of-file, different from 'lseek() + read()' behaviour.
- * Returning '0 bytes read' and 'osl_File_E_None' instead.
- */
- nBytes = 0;
- }
-
-#else /* LINUX || SOLARIS */
-
- if (-1 == ::lseek (pHandleImpl->fd, nOffset, SEEK_SET))
- return oslTranslateFileError(OSL_FET_ERROR, errno);
-
- ssize_t nBytes = ::read(pHandleImpl->fd, pBuffer, nBytesRequested);
-
-#endif /* LINUX || SOLARIS */
-
- if (-1 == nBytes)
- return oslTranslateFileError(OSL_FET_ERROR, errno);
-
- *pBytesRead = nBytes;
- return osl_File_E_None;
+ // read at specified fileptr
+ return pImpl->readFileAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
}
/*******************************************
@@ -1449,10 +1152,14 @@ SAL_CALL osl_writeFileAt (
sal_uInt64 uBytesToWrite,
sal_uInt64* pBytesWritten)
{
- oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesWritten))
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten))
return osl_File_E_INVAL;
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
+ return osl_File_E_BADF;
static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
if (g_limit_off_t < uOffset)
@@ -1464,189 +1171,141 @@ SAL_CALL osl_writeFileAt (
return osl_File_E_OVERFLOW;
size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite);
-#if defined(LINUX) || defined(SOLARIS)
-
- ssize_t nBytes = ::pwrite(pHandleImpl->fd, pBuffer, nBytesToWrite, nOffset);
+ // write at specified fileptr
+ return pImpl->writeFileAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten);
+}
-#else /* LINUX || SOLARIS */
+/****************************************************************************/
+/* osl_isEndOfFile */
+/****************************************************************************/
+oslFileError
+SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
+{
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if (-1 == ::lseek(pHandleImpl->fd, nOffset, SEEK_SET))
- return oslTranslateFileError(OSL_FET_ERROR, errno);
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pIsEOF))
+ return osl_File_E_INVAL;
- ssize_t nBytes = ::write(pHandleImpl->fd, pBuffer, nBytesToWrite);
+ *pIsEOF = (pImpl->getPos() == pImpl->getSize());
+ return osl_File_E_None;
+}
-#endif /* LINUX || SOLARIS */
+/************************************************
+ * osl_getFilePos
+ ***********************************************/
+oslFileError
+SAL_CALL osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
+{
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if (-1 == nBytes)
- return oslTranslateFileError(OSL_FET_ERROR, errno);
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pPos))
+ return osl_File_E_INVAL;
- *pBytesWritten = nBytes;
+ *pPos = pImpl->getPos();
return osl_File_E_None;
}
/*******************************************
osl_setFilePos
********************************************/
-
-oslFileError osl_setFilePos( oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos )
+oslFileError
+SAL_CALL osl_setFilePos (oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffset)
{
- oslFileHandleImpl* pHandleImpl=0;
- int nRet=0;
- off_t nOffset=0;
-
- pHandleImpl = (oslFileHandleImpl*) Handle;
- if ( pHandleImpl == 0 )
- {
- return osl_File_E_INVAL;
- }
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ( pHandleImpl->fd < 0 )
- {
+ if ((0 == pImpl) || (-1 == pImpl->m_fd))
return osl_File_E_INVAL;
- }
- /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
- if ( uPos > LONG_MAX )
- {
+ static sal_Int64 const g_limit_off_t = std::numeric_limits< off_t >::max();
+ if (g_limit_off_t < uOffset)
return osl_File_E_OVERFLOW;
- }
-
- nOffset=(off_t)uPos;
+ off_t nPos = 0, nOffset = sal::static_int_cast< off_t >(uOffset);
switch(uHow)
{
case osl_Pos_Absolut:
- nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_SET);
+ if (0 > nOffset)
+ return osl_File_E_INVAL;
break;
case osl_Pos_Current:
- nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_CUR);
+ nPos = sal::static_int_cast< off_t >(pImpl->getPos());
+ if ((0 > nOffset) && (-1*nOffset > nPos))
+ return osl_File_E_INVAL;
+ if (g_limit_off_t < nPos + nOffset)
+ return osl_File_E_OVERFLOW;
break;
case osl_Pos_End:
- nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_END);
+ nPos = sal::static_int_cast< off_t >(pImpl->getSize());
+ if ((0 > nOffset) && (-1*nOffset > nPos))
+ return osl_File_E_INVAL;
+ if (g_limit_off_t < nPos + nOffset)
+ return osl_File_E_OVERFLOW;
break;
default:
return osl_File_E_INVAL;
}
- if ( nOffset < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- return osl_File_E_None;
-}
-
-/************************************************
- * osl_getFilePos
- ***********************************************/
-
-oslFileError osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
-{
- oslFileHandleImpl* pHandleImpl=0;
- off_t nOffset=0;
- int nRet=0;
-
- pHandleImpl = (oslFileHandleImpl*) Handle;
- if ( pHandleImpl == 0 || pPos == 0)
- {
- return osl_File_E_INVAL;
- }
-
- if ( pHandleImpl->fd < 0 )
- {
- return osl_File_E_INVAL;
- }
-
- nOffset = lseek(pHandleImpl->fd,0,SEEK_CUR);
-
- if (nOffset < 0)
- {
- nRet =errno;
-
- /* *pPos =0; */
-
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- *pPos=nOffset;
-
- return osl_File_E_None;
+ return pImpl->setPos (nPos + nOffset);
}
/****************************************************************************
* osl_getFileSize
****************************************************************************/
-
-oslFileError osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
+oslFileError
+SAL_CALL osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
{
- oslFileHandleImpl* pHandleImpl=(oslFileHandleImpl*) Handle;
- if (pHandleImpl == 0)
- return osl_File_E_INVAL;
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- struct stat file_stat;
- if (fstat(pHandleImpl->fd, &file_stat) == -1)
- return oslTranslateFileError(OSL_FET_ERROR, errno);
+ if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pSize))
+ return osl_File_E_INVAL;
- *pSize = file_stat.st_size;
+ *pSize = pImpl->getSize();
return osl_File_E_None;
}
/************************************************
* osl_setFileSize
***********************************************/
-
-oslFileError osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
+oslFileError
+SAL_CALL osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
{
- oslFileHandleImpl* pHandleImpl=0;
- off_t nOffset=0;
-
- pHandleImpl = (oslFileHandleImpl*) Handle;
- if ( pHandleImpl == 0 )
- {
- return osl_File_E_INVAL;
- }
+ FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ( pHandleImpl->fd < 0 )
- {
+ if ((0 == pImpl) || (-1 == pImpl->m_fd))
return osl_File_E_INVAL;
- }
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
+ return osl_File_E_BADF;
- /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
- if ( uSize > LONG_MAX )
- {
+ static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
+ if (g_limit_off_t < uSize)
return osl_File_E_OVERFLOW;
- }
+ off_t const nSize = sal::static_int_cast< off_t >(uSize);
+
+ oslFileError result = pImpl->syncFile();
+ if (result != osl_File_E_None)
+ return (result);
- nOffset = (off_t)uSize;
- if (ftruncate (pHandleImpl->fd, nOffset) < 0)
+ if (-1 == ftruncate (pImpl->m_fd, nSize))
{
/* Failure. Try fallback algorithm */
- oslFileError result;
- struct stat aStat;
- off_t nCurPos;
+ off_t nCurPos;
/* Save original result */
result = oslTranslateFileError (OSL_FET_ERROR, errno);
PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
/* Check against current size. Fail upon 'shrink' */
- if (fstat (pHandleImpl->fd, &aStat) < 0)
- {
- PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
- return (result);
- }
- if ((0 <= nOffset) && (nOffset <= aStat.st_size))
+ if (uSize <= pImpl->getSize())
{
/* Failure upon 'shrink'. Return original result */
return (result);
}
- /* Save current position */
- nCurPos = (off_t)lseek (pHandleImpl->fd, (off_t)0, SEEK_CUR);
+ /* Save current position *//* @@@ pImpl->m_offset @@@ */
+ nCurPos = (off_t)lseek (pImpl->m_fd, (off_t)0, SEEK_CUR);
if (nCurPos == (off_t)(-1))
{
PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
@@ -1654,2095 +1313,31 @@ oslFileError osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
}
/* Try 'expand' via 'lseek()' and 'write()' */
- if (lseek (pHandleImpl->fd, (off_t)(nOffset - 1), SEEK_SET) < 0)
+ if (lseek (pImpl->m_fd, (off_t)(nSize - 1), SEEK_SET) < 0)
{
PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
return (result);
}
- if (write (pHandleImpl->fd, (char*)"", (size_t)1) < 0)
+ if (write (pImpl->m_fd, (char*)"", (size_t)1) < 0)
{
/* Failure. Restore saved position */
PERROR("ftruncate: write", "Out osl_setFileSize [error]\n");
- if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
+ if (lseek (pImpl->m_fd, (off_t)nCurPos, SEEK_SET) < 0)
{
-#ifdef DEBUG_OSL_FILE
- perror("ftruncate: lseek");
-#endif /* DEBUG_OSL_FILE */
+ PERROR("ftruncate: lseek", "ignoring");
}
return (result);
}
/* Success. Restore saved position */
- if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
+ if (lseek (pImpl->m_fd, (off_t)nCurPos, SEEK_SET) < 0)
{
PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
return (result);
}
}
- return (osl_File_E_None);
-}
-
-/*###############################################*/
-oslFileError SAL_CALL osl_syncFile(oslFileHandle Handle)
-{
- oslFileHandleImpl* handle_impl = (oslFileHandleImpl*)Handle;
-
- if (handle_impl == 0)
- return osl_File_E_INVAL;
-
- if (fsync(handle_impl->fd) == -1)
- return oslTranslateFileError(OSL_FET_ERROR, errno);
-
- return osl_File_E_None;
-}
-
-/******************************************************************************
- *
- * C-String Versions of Exported Module Functions
- *
- *****************************************************************************/
-
-#ifdef HAVE_STATFS_H
-
-#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
-# define __OSL_STATFS_STRUCT struct statfs
-# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
-# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
-# define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
-# define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
-
-/* always return true if queried for the properties of
- the file system. If you think this is wrong under any
- of the target platforms fix it!!!! */
-# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
-# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
-#endif /* FREEBSD || NETBSD || MACOSX */
-
-#if defined(LINUX)
-# define __OSL_NFS_SUPER_MAGIC 0x6969
-# define __OSL_SMB_SUPER_MAGIC 0x517B
-# define __OSL_MSDOS_SUPER_MAGIC 0x4d44
-# define __OSL_NTFS_SUPER_MAGIC 0x5346544e
-# define __OSL_STATFS_STRUCT struct statfs
-# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
-# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
-# define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
-# define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
-# define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
-# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
-# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
-#endif /* LINUX */
-
-#if defined(SOLARIS) || defined(IRIX)
-# define __OSL_STATFS_STRUCT struct statvfs
-# define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
-# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
-# define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
-# define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
-
-/* always return true if queried for the properties of
- the file system. If you think this is wrong under any
- of the target platforms fix it!!!! */
-# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
-# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
-#endif /* SOLARIS || IRIX*/
-
-# define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
-
-#else /* no statfs available */
-
-# define __OSL_STATFS_STRUCT struct dummy {int i;}
-# define __OSL_STATFS_INIT(a) ((void)0)
-# define __OSL_STATFS(dir, sfs) (1)
-# define __OSL_STATFS_ISREMOTE(sfs) (0)
-# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
-# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
-#endif /* HAVE_STATFS_H */
-
-
-static oslFileError osl_psz_getVolumeInformation (
- const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
-{
- __OSL_STATFS_STRUCT sfs;
-
- if (!pInfo)
- return osl_File_E_INVAL;
-
- __OSL_STATFS_INIT(sfs);
-
- pInfo->uValidFields = 0;
- pInfo->uAttributes = 0;
-
- if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
- {
- oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
- return (result);
- }
-
- /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
- if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
- {
- if (__OSL_STATFS_ISREMOTE(sfs))
- pInfo->uAttributes |= osl_Volume_Attribute_Remote;
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
- }
-
- if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
- {
- if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
- pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
-
- if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
- pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
- }
-
- pInfo->uTotalSpace = 0;
- pInfo->uFreeSpace = 0;
- pInfo->uUsedSpace = 0;
-
-#if defined(__OSL_STATFS_BLKSIZ)
-
- if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
- (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
- {
- pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
- pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
- pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
- }
-
- if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
- (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
- {
- pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
-
- if (getuid() == 0)
- pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
- else
- pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
- }
-
-#endif /* __OSL_STATFS_BLKSIZ */
-
- if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
- (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
- {
- pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
- pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
- }
-
- pInfo->uMaxNameLength = 0;
- if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
- {
- long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
- if (nLen > 0)
- {
- pInfo->uMaxNameLength = (sal_uInt32)nLen;
- pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
- }
- }
-
- pInfo->uMaxPathLength = 0;
- if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
- {
- long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
- if (nLen > 0)
- {
- pInfo->uMaxPathLength = (sal_uInt32)nLen;
- pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
- }
- }
-
-#if defined(__OSL_STATFS_TYPENAME)
-
- if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
- {
- rtl_string2UString(
- &(pInfo->ustrFileSystemName),
- __OSL_STATFS_TYPENAME(sfs),
- rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
- osl_getThreadTextEncoding(),
- OUSTRING_TO_OSTRING_CVTFLAGS);
- OSL_ASSERT(pInfo->ustrFileSystemName != 0);
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
- }
-
-#endif /* __OSL_STATFS_TYPENAME */
-
- if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
- {
- /* FIXME: check also entries in mntent for the device
- and fill it with correct values */
-
- *pInfo->pDeviceHandle = osl_isFloppyDrive(pszDirectory);
-
- if (*pInfo->pDeviceHandle)
- {
- pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
- pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
- pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
- }
- }
- return osl_File_E_None;
-}
-
-/*************************************
- * osl_psz_setFileAttributes
- ************************************/
-
-static oslFileError osl_psz_setFileAttributes( const sal_Char* pszFilePath, sal_uInt64 uAttributes )
-{
- oslFileError osl_error = osl_File_E_None;
- mode_t nNewMode = 0;
-
- OSL_ENSURE(!(osl_File_Attribute_Hidden & uAttributes), "osl_File_Attribute_Hidden doesn't work under Unix");
-
- if (uAttributes & osl_File_Attribute_OwnRead)
- nNewMode |= S_IRUSR;
-
- if (uAttributes & osl_File_Attribute_OwnWrite)
- nNewMode|=S_IWUSR;
-
- if (uAttributes & osl_File_Attribute_OwnExe)
- nNewMode|=S_IXUSR;
-
- if (uAttributes & osl_File_Attribute_GrpRead)
- nNewMode|=S_IRGRP;
-
- if (uAttributes & osl_File_Attribute_GrpWrite)
- nNewMode|=S_IWGRP;
-
- if (uAttributes & osl_File_Attribute_GrpExe)
- nNewMode|=S_IXGRP;
-
- if (uAttributes & osl_File_Attribute_OthRead)
- nNewMode|=S_IROTH;
-
- if (uAttributes & osl_File_Attribute_OthWrite)
- nNewMode|=S_IWOTH;
-
- if (uAttributes & osl_File_Attribute_OthExe)
- nNewMode|=S_IXOTH;
-
- if (chmod(pszFilePath, nNewMode) < 0)
- osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
-
- return osl_error;
-}
-
-/******************************************
- * osl_psz_setFileTime
- *****************************************/
-
-static oslFileError osl_psz_setFileTime( const sal_Char* pszFilePath,
- const TimeValue* /*pCreationTime*/,
- const TimeValue* pLastAccessTime,
- const TimeValue* pLastWriteTime )
-{
- int nRet=0;
- struct utimbuf aTimeBuffer;
- struct stat aFileStat;
-#ifdef DEBUG_OSL_FILE
- struct tm* pTM=0;
-#endif
-
- nRet = lstat(pszFilePath,&aFileStat);
-
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"File Times are (in localtime):\n");
- pTM=localtime(&aFileStat.st_ctime);
- fprintf(stderr,"CreationTime is '%s'\n",asctime(pTM));
- pTM=localtime(&aFileStat.st_atime);
- fprintf(stderr,"AccessTime is '%s'\n",asctime(pTM));
- pTM=localtime(&aFileStat.st_mtime);
- fprintf(stderr,"Modification is '%s'\n",asctime(pTM));
-
- fprintf(stderr,"File Times are (in UTC):\n");
- fprintf(stderr,"CreationTime is '%s'\n",ctime(&aFileStat.st_ctime));
- fprintf(stderr,"AccessTime is '%s'\n",ctime(&aTimeBuffer.actime));
- fprintf(stderr,"Modification is '%s'\n",ctime(&aTimeBuffer.modtime));
-#endif
-
- if ( pLastAccessTime != 0 )
- {
- aTimeBuffer.actime=pLastAccessTime->Seconds;
- }
- else
- {
- aTimeBuffer.actime=aFileStat.st_atime;
- }
-
- if ( pLastWriteTime != 0 )
- {
- aTimeBuffer.modtime=pLastWriteTime->Seconds;
- }
- else
- {
- aTimeBuffer.modtime=aFileStat.st_mtime;
- }
-
- /* mfe: Creation time not used here! */
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"File Times are (in localtime):\n");
- pTM=localtime(&aFileStat.st_ctime);
- fprintf(stderr,"CreationTime now '%s'\n",asctime(pTM));
- pTM=localtime(&aTimeBuffer.actime);
- fprintf(stderr,"AccessTime now '%s'\n",asctime(pTM));
- pTM=localtime(&aTimeBuffer.modtime);
- fprintf(stderr,"Modification now '%s'\n",asctime(pTM));
-
- fprintf(stderr,"File Times are (in UTC):\n");
- fprintf(stderr,"CreationTime now '%s'\n",ctime(&aFileStat.st_ctime));
- fprintf(stderr,"AccessTime now '%s'\n",ctime(&aTimeBuffer.actime));
- fprintf(stderr,"Modification now '%s'\n",ctime(&aTimeBuffer.modtime));
-#endif
-
- nRet=utime(pszFilePath,&aTimeBuffer);
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- return osl_File_E_None;
-}
-
-
-/*****************************************
- * osl_psz_removeFile
- ****************************************/
-
-static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
-{
- int nRet=0;
- struct stat aStat;
-
- nRet = lstat(pszPath,&aStat);
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- if ( S_ISDIR(aStat.st_mode) )
- {
- return osl_File_E_ISDIR;
- }
-
- nRet = unlink(pszPath);
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- return osl_File_E_None;
-}
-
-/*****************************************
- * osl_psz_createDirectory
- ****************************************/
-
-static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
-{
- int nRet=0;
- int mode = S_IRWXU | S_IRWXG | S_IRWXO;
-
- nRet = mkdir(pszPath,mode);
-
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- return osl_File_E_None;
-}
-
-/*****************************************
- * osl_psz_removeDirectory
- ****************************************/
-
-static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
-{
- int nRet=0;
-
- nRet = rmdir(pszPath);
-
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
+ OSL_FILE_TRACE("osl_setFileSize(%d, %lld) => %ld", pImpl->m_fd, pImpl->getSize(), nSize);
+ pImpl->m_size = sal::static_int_cast< sal_uInt64 >(nSize);
return osl_File_E_None;
}
-
-/*****************************************
- * oslDoMoveFile
- ****************************************/
-
-static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
-{
- oslFileError tErr=osl_File_E_invalidError;
-
- tErr = osl_psz_moveFile(pszPath,pszDestPath);
- if ( tErr == osl_File_E_None )
- {
- return tErr;
- }
-
- if ( tErr != osl_File_E_XDEV )
- {
- return tErr;
- }
-
- tErr=osl_psz_copyFile(pszPath,pszDestPath);
-
- if ( tErr != osl_File_E_None )
- {
- oslFileError tErrRemove;
- tErrRemove=osl_psz_removeFile(pszDestPath);
- return tErr;
- }
-
- tErr=osl_psz_removeFile(pszPath);
-
- return tErr;
-}
-
-/*****************************************
- * osl_psz_moveFile
- ****************************************/
-
-static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
-{
-
- int nRet = 0;
-
- nRet = rename(pszPath,pszDestPath);
-
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- return osl_File_E_None;
-}
-
-/*****************************************
- * osl_psz_copyFile
- ****************************************/
-
-static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
-{
- time_t nAcTime=0;
- time_t nModTime=0;
- uid_t nUID=0;
- gid_t nGID=0;
- int nRet=0;
- mode_t nMode=0;
- struct stat aFileStat;
- oslFileError tErr=osl_File_E_invalidError;
- size_t nSourceSize=0;
- int DestFileExists=1;
-
- /* mfe: does the source file really exists? */
- nRet = lstat(pszPath,&aFileStat);
-
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- /* mfe: we do only copy files here! */
- if ( S_ISDIR(aFileStat.st_mode) )
- {
- return osl_File_E_ISDIR;
- }
-
- nSourceSize=(size_t)aFileStat.st_size;
- nMode=aFileStat.st_mode;
- nAcTime=aFileStat.st_atime;
- nModTime=aFileStat.st_mtime;
- nUID=aFileStat.st_uid;
- nGID=aFileStat.st_gid;
-
- nRet = stat(pszDestPath,&aFileStat);
- if ( nRet < 0 )
- {
- nRet=errno;
-
- if ( nRet == ENOENT )
- {
- DestFileExists=0;
- }
-/* return oslTranslateFileError(nRet);*/
- }
-
- /* mfe: the destination file must not be a directory! */
- if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
- {
- return osl_File_E_ISDIR;
- }
- else
- {
- /* mfe: file does not exists or is no dir */
- }
-
- tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
-
- if ( tErr != osl_File_E_None )
- {
- return tErr;
- }
-
- /*
- * mfe: ignore return code
- * since only the success of the copy is
- * important
- */
- oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
-
- return tErr;
-}
-
-
-/******************************************************************************
- *
- * Utility Functions
- *
- *****************************************************************************/
-
-/*****************************************
- * oslDoCopy
- ****************************************/
-
-#define TMP_DEST_FILE_EXTENSION ".osl-tmp"
-
-static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
-{
- int nRet=0;
- sal_Char pszTmpDestFile[PATH_MAX];
- size_t size_tmp_dest_buff = sizeof(pszTmpDestFile);
-
- /* Quick fix for #106048, the whole copy file function seems
- to be erroneous anyway and needs to be rewritten.
- Besides osl_copyFile is currently not used from OO/SO code.
- */
- memset(pszTmpDestFile, 0, size_tmp_dest_buff);
-
- if ( DestFileExists )
- {
- strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
-
- if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION)) >= size_tmp_dest_buff)
- return osl_File_E_NAMETOOLONG;
-
- strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION, strlen(TMP_DEST_FILE_EXTENSION));
-
- /* FIXME: what if pszTmpDestFile already exists? */
- /* with getcanonical??? */
- nRet=rename(pszDestFileName,pszTmpDestFile);
- }
-
- /* mfe: should be S_ISREG */
- if ( !S_ISLNK(nMode) )
- {
- /* copy SourceFile to DestFile */
- nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
- }
- /* mfe: OK redundant at the moment */
- else if ( S_ISLNK(nMode) )
- {
- nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
- }
- else
- {
- /* mfe: what to do here? */
- nRet=ENOSYS;
- }
-
- if ( nRet > 0 && DestFileExists == 1 )
- {
- unlink(pszDestFileName);
- rename(pszTmpDestFile,pszDestFileName);
- }
-
- if ( nRet > 0 )
- {
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- if ( DestFileExists == 1 )
- {
- unlink(pszTmpDestFile);
- }
-
- return osl_File_E_None;
-}
-
-/*****************************************
- * oslChangeFileModes
- ****************************************/
-
-static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
-{
- int nRet=0;
- struct utimbuf aTimeBuffer;
-
- nRet = chmod(pszFileName,nMode);
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- aTimeBuffer.actime=nAcTime;
- aTimeBuffer.modtime=nModTime;
- nRet=utime(pszFileName,&aTimeBuffer);
- if ( nRet < 0 )
- {
- nRet=errno;
- return oslTranslateFileError(OSL_FET_ERROR, nRet);
- }
-
- if ( nUID != getuid() )
- {
- nUID=getuid();
- }
-
- nRet=chown(pszFileName,nUID,nGID);
- if ( nRet < 0 )
- {
- nRet=errno;
-
- /* mfe: do not return an error here! */
- /* return oslTranslateFileError(nRet);*/
- }
-
- return osl_File_E_None;
-}
-
-/*****************************************
- * oslDoCopyLink
- ****************************************/
-
-static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
-{
- int nRet=0;
-
- /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
- /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
- sal_Char pszLinkContent[PATH_MAX];
-
- pszLinkContent[0] = '\0';
-
- nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX);
-
- if ( nRet < 0 )
- {
- nRet=errno;
- return nRet;
- }
- else
- pszLinkContent[ nRet ] = 0;
-
- nRet = symlink(pszLinkContent,pszDestFileName);
-
- if ( nRet < 0 )
- {
- nRet=errno;
- return nRet;
- }
-
- return 0;
-}
-
-/*****************************************
- * oslDoCopyFile
- ****************************************/
-
-static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
-{
- int SourceFileFD=0;
- int DestFileFD=0;
- int nRet=0;
- void* pSourceFile=0;
-
- SourceFileFD=open(pszSourceFileName,O_RDONLY);
- if ( SourceFileFD < 0 )
- {
- nRet=errno;
- return nRet;
- }
-
- DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT, mode);
-
- if ( DestFileFD < 0 )
- {
- nRet=errno;
- close(SourceFileFD);
- return nRet;
- }
-
- /* HACK: because memory mapping fails on various
- platforms if the size of the source file is 0 byte */
- if (0 == nSourceSize)
- {
- close(SourceFileFD);
- close(DestFileFD);
- return 0;
- }
-
- /* FIXME doCopy: fall back code for systems not having mmap */
- /* mmap file -- open dest file -- write once -- fsync it */
- pSourceFile=mmap(0,nSourceSize,PROT_READ,MAP_PRIVATE,SourceFileFD,0);
-
- if ( pSourceFile == MAP_FAILED )
- {
- /* it's important to set nRet before the hack
- otherwise errno may be changed by lstat */
- nRet = errno;
- close(SourceFileFD);
- close(DestFileFD);
-
- return nRet;
- }
-
- nRet = write(DestFileFD,pSourceFile,nSourceSize);
-
- /* #112584# if 'write' could not write the requested number of bytes
- we have to fail of course; because it's not exactly specified if 'write'
- sets errno if less than requested byte could be written we set nRet
- explicitly to ENOSPC */
- if ((nRet < 0) || (nRet != sal::static_int_cast< int >(nSourceSize)))
- {
- if (nRet < 0)
- nRet = errno;
- else
- nRet = ENOSPC;
-
- close(SourceFileFD);
- close(DestFileFD);
- munmap((char*)pSourceFile,nSourceSize);
- return nRet;
- }
-
- nRet = munmap((char*)pSourceFile,nSourceSize);
- if ( nRet < 0 )
- {
- nRet=errno;
- close(SourceFileFD);
- close(DestFileFD);
- return nRet;
- }
-
- close(SourceFileFD);
-
- // Removed call to 'fsync' again (#112584#) and instead
- // evaluate the return value of 'close' in order to detect
- // and report ENOSPC and other erronous conditions on close
- if (close(DestFileFD) == -1)
- return errno;
- else
- return 0;
-}
-
-/*****************************************
- * oslMakeUStrFromPsz
- ****************************************/
-
-static rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
-{
- rtl_string2UString(
- ustrValid,
- pszStr,
- rtl_str_getLength( pszStr ),
- osl_getThreadTextEncoding(),
- OUSTRING_TO_OSTRING_CVTFLAGS );
- OSL_ASSERT(*ustrValid != 0);
-
- return *ustrValid;
-}
-
-/*****************************************************************************
- * UnicodeToText
- * converting unicode to text manually saves us the penalty of a temporary
- * rtl_String object.
- ****************************************************************************/
-
-int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
-{
- rtl_UnicodeToTextConverter hConverter;
- sal_uInt32 nInfo;
- sal_Size nSrcChars, nDestBytes;
-
- /* stolen from rtl/string.c */
- hConverter = rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
-
- nDestBytes = rtl_convertUnicodeToText( hConverter, 0, uniText, uniTextLen,
- buffer, bufLen,
- OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH,
- &nInfo, &nSrcChars );
-
- rtl_destroyUnicodeToTextConverter( hConverter );
-
- if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
- {
- errno = EOVERFLOW;
- return 0;
- }
-
- /* ensure trailing '\0' */
- buffer[nDestBytes] = '\0';
-
- return nDestBytes;
-}
-
-/*****************************************************************************
- TextToUnicode
-
- @param text
- The text to convert.
-
- @param text_buffer_size
- The number of characters.
-
- @param unic_text
- The unicode buffer.
-
- @param unic_text_buffer_size
- The size in characters of the unicode buffer.
-
- ****************************************************************************/
-
-int TextToUnicode(
- const char* text,
- size_t text_buffer_size,
- sal_Unicode* unic_text,
- sal_Int32 unic_text_buffer_size)
-{
- rtl_TextToUnicodeConverter hConverter;
- sal_uInt32 nInfo;
- sal_Size nSrcChars;
- sal_Size nDestBytes;
-
- /* stolen from rtl/string.c */
- hConverter = rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
-
- nDestBytes = rtl_convertTextToUnicode(hConverter,
- 0,
- text, text_buffer_size,
- unic_text, unic_text_buffer_size,
- OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH,
- &nInfo, &nSrcChars);
-
- rtl_destroyTextToUnicodeConverter(hConverter);
-
- if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
- {
- errno = EOVERFLOW;
- return 0;
- }
-
- /* ensure trailing '\0' */
- unic_text[nDestBytes] = '\0';
-
- return nDestBytes;
-}
-
-/******************************************************************************
- *
- * GENERIC FLOPPY FUNCTIONS
- *
- *****************************************************************************/
-
-
-/*****************************************
- * osl_unmountVolumeDevice
- ****************************************/
-
-oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
-{
- oslFileError tErr = osl_File_E_NOSYS;
-
- tErr = osl_unmountFloppy(Handle);
-
- /* Perhaps current working directory is set to mount point */
-
- if ( tErr )
- {
- sal_Char *pszHomeDir = getenv("HOME");
-
- if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
- {
- /* try again */
-
- tErr = osl_unmountFloppy(Handle);
-
- OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
- }
- }
-
- return tErr;
-}
-
-/*****************************************
- * osl_automountVolumeDevice
- ****************************************/
-
-oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
-{
- oslFileError tErr = osl_File_E_NOSYS;
-
- tErr = osl_mountFloppy(Handle);
-
- return tErr;
-}
-
-/*****************************************
- * osl_getVolumeDeviceMountPath
- ****************************************/
-
-oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
-{
- oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
- sal_Char Buffer[PATH_MAX];
-
- Buffer[0] = '\0';
-
- if ( pItem == 0 || pstrPath == 0 )
- {
- return osl_File_E_INVAL;
- }
-
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
- return osl_File_E_INVAL;
- }
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"Handle is:\n");
- osl_printFloppyHandle(pItem);
-#endif
-
- snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
-#endif
-
- oslMakeUStrFromPsz(Buffer, pstrPath);
-
- return osl_File_E_None;
-}
-
-/*****************************************
- * osl_acquireVolumeDeviceHandle
- ****************************************/
-
-oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
-{
- oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
-
- if ( pItem == 0 )
- {
- return osl_File_E_INVAL;
- }
-
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
- return osl_File_E_INVAL;
- }
-
- ++pItem->RefCount;
-
- return osl_File_E_None;
-}
-
-/*****************************************
- * osl_releaseVolumeDeviceHandle
- ****************************************/
-
-oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
-{
- oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
-
- if ( pItem == 0 )
- {
- return osl_File_E_INVAL;
- }
-
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
- return osl_File_E_INVAL;
- }
-
- --pItem->RefCount;
-
- if ( pItem->RefCount == 0 )
- {
- rtl_freeMemory(pItem);
- }
-
- return osl_File_E_None;
-}
-
-#ifndef MACOSX
-
-/*****************************************
- * osl_newVolumeDeviceHandleImpl
- ****************************************/
-
-static oslVolumeDeviceHandleImpl* osl_newVolumeDeviceHandleImpl()
-{
- oslVolumeDeviceHandleImpl* pHandle;
- const size_t nSizeOfHandle = sizeof(oslVolumeDeviceHandleImpl);
-
- pHandle = (oslVolumeDeviceHandleImpl*) rtl_allocateMemory (nSizeOfHandle);
- if (pHandle != NULL)
- {
- pHandle->ident[0] = 'O';
- pHandle->ident[1] = 'V';
- pHandle->ident[2] = 'D';
- pHandle->ident[3] = 'H';
- pHandle->pszMountPoint[0] = '\0';
- pHandle->pszFilePath[0] = '\0';
- pHandle->pszDevice[0] = '\0';
- pHandle->RefCount = 1;
- }
- return pHandle;
-}
-
-/*****************************************
- * osl_freeVolumeDeviceHandleImpl
- ****************************************/
-
-static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
-{
- if (pHandle != NULL)
- rtl_freeMemory (pHandle);
-}
-#endif
-
-/******************************************************************************
- *
- * SOLARIS FLOPPY FUNCTIONS
- *
- *****************************************************************************/
-
-#if defined(SOLARIS)
-/* compare a given devicename with the typical device names on a Solaris box */
-static sal_Bool
-osl_isAFloppyDevice (const char* pDeviceName)
-{
- const char* pFloppyDevice [] = {
- "/dev/fd", "/dev/rfd",
- "/dev/diskette", "/dev/rdiskette",
- "/vol/dev/diskette", "/vol/dev/rdiskette"
- };
-
- int i;
- for (i = 0; i < (sizeof(pFloppyDevice)/sizeof(pFloppyDevice[0])); i++)
- {
- if (strncmp(pDeviceName, pFloppyDevice[i], strlen(pFloppyDevice[i])) == 0)
- return sal_True;
- }
- return sal_False;
-}
-
-/* compare two directories whether the first may be a parent of the second. this
- * does not realpath() resolving */
-static sal_Bool
-osl_isAParentDirectory (const char* pParentDir, const char* pSubDir)
-{
- return strncmp(pParentDir, pSubDir, strlen(pParentDir)) == 0;
-}
-
-/* the name of the routine is obviously silly. But anyway create a
- * oslVolumeDeviceHandle with correct mount point, device name and a resolved filepath
- * only if pszPath points to file or directory on a floppy */
-static oslVolumeDeviceHandle
-osl_isFloppyDrive(const sal_Char* pszPath)
-{
- FILE* pMountTab;
- struct mnttab aMountEnt;
- oslVolumeDeviceHandleImpl* pHandle;
-
- if ((pHandle = osl_newVolumeDeviceHandleImpl()) == NULL)
- {
- return NULL;
- }
- if (realpath(pszPath, pHandle->pszFilePath) == NULL)
- {
- osl_freeVolumeDeviceHandleImpl (pHandle);
- return NULL;
- }
- if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
- {
- osl_freeVolumeDeviceHandleImpl (pHandle);
- return NULL;
- }
-
- while (getmntent(pMountTab, &aMountEnt) == 0)
- {
- const char *pMountPoint = aMountEnt.mnt_mountp;
- const char *pDevice = aMountEnt.mnt_special;
- if ( osl_isAParentDirectory (aMountEnt.mnt_mountp, pHandle->pszFilePath)
- && osl_isAFloppyDevice (aMountEnt.mnt_special))
- {
- /* skip the last item for it is the name of the disk */
- char * pc = strrchr( aMountEnt.mnt_special, '/' );
-
- if ( NULL != pc )
- {
- int len = pc - aMountEnt.mnt_special;
-
- strncpy( pHandle->pszDevice, aMountEnt.mnt_special, len );
- pHandle->pszDevice[len] = '\0';
- }
- else
- {
- /* #106048 use save str functions to avoid buffer overflows */
- memset(pHandle->pszDevice, 0, sizeof(pHandle->pszDevice));
- strncpy(pHandle->pszDevice, aMountEnt.mnt_special, sizeof(pHandle->pszDevice) - 1);
- }
-
- /* remember the mount point */
- memset(pHandle->pszMountPoint, 0, sizeof(pHandle->pszMountPoint));
- strncpy(pHandle->pszMountPoint, aMountEnt.mnt_mountp, sizeof(pHandle->pszMountPoint) - 1);
-
- fclose (pMountTab);
- return pHandle;
- }
- }
-
- fclose (pMountTab);
- osl_freeVolumeDeviceHandleImpl (pHandle);
- return NULL;
-}
-
-static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
-{
- FILE* pMountTab;
- struct mnttab aMountEnt;
- oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
-
- int nRet=0;
- sal_Char pszCmd[512] = "";
-
- if ( pHandle == 0 )
- return osl_File_E_INVAL;
-
- /* FIXME: don't know what this is good for */
- if ( pHandle->ident[0] != 'O' || pHandle->ident[1] != 'V' || pHandle->ident[2] != 'D' || pHandle->ident[3] != 'H' )
- return osl_File_E_INVAL;
-
- snprintf(pszCmd, sizeof(pszCmd), "eject -q %s > /dev/null 2>&1", pHandle->pszDevice);
-
- nRet = system( pszCmd );
-
- switch ( WEXITSTATUS(nRet) )
- {
- case 0:
- {
- /* lookup the device in mount tab again */
- if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
- return osl_File_E_BUSY;
-
- while (getmntent(pMountTab, &aMountEnt) == 0)
- {
- const char *pMountPoint = aMountEnt.mnt_mountp;
- const char *pDevice = aMountEnt.mnt_special;
- if ( 0 == strncmp( pHandle->pszDevice, aMountEnt.mnt_special, strlen(pHandle->pszDevice) ) )
- {
- memset(pHandle->pszMountPoint, 0, sizeof(pHandle->pszMountPoint));
- strncpy (pHandle->pszMountPoint, aMountEnt.mnt_mountp, sizeof(pHandle->pszMountPoint) - 1);
-
- fclose (pMountTab);
- return osl_File_E_None;
- }
- }
-
- fclose (pMountTab);
- return osl_File_E_BUSY;
- }
- //break; // break not necessary here, see return statements before
-
- case 1:
- return osl_File_E_BUSY;
-
- default:
- break;
- }
-
- return osl_File_E_BUSY;
-}
-
-static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
-{
-// FILE* pMountTab;
-// struct mnttab aMountEnt;
- oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
-
- int nRet=0;
- sal_Char pszCmd[512] = "";
-
- if ( pHandle == 0 )
- return osl_File_E_INVAL;
-
- /* FIXME: don't know what this is good for */
- if ( pHandle->ident[0] != 'O' || pHandle->ident[1] != 'V' || pHandle->ident[2] != 'D' || pHandle->ident[3] != 'H' )
- return osl_File_E_INVAL;
-
- snprintf(pszCmd, sizeof(pszCmd), "eject %s > /dev/null 2>&1", pHandle->pszDevice);
-
- nRet = system( pszCmd );
-
- switch ( WEXITSTATUS(nRet) )
- {
- case 0:
- {
- FILE* pMountTab;
- struct mnttab aMountEnt;
-
- /* lookup if device is still in mount tab */
- if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
- return osl_File_E_BUSY;
-
- while (getmntent(pMountTab, &aMountEnt) == 0)
- {
- const char *pMountPoint = aMountEnt.mnt_mountp;
- const char *pDevice = aMountEnt.mnt_special;
- if ( 0 == strncmp( pHandle->pszDevice, aMountEnt.mnt_special, strlen(pHandle->pszDevice) ) )
- {
- fclose (pMountTab);
- return osl_File_E_BUSY;
- }
- }
-
- fclose (pMountTab);
- pHandle->pszMountPoint[0] = 0;
- return osl_File_E_None;
- }
-
- //break; //break not necessary, see return statements before
-
- case 1:
- return osl_File_E_NODEV;
-
- case 4:
- pHandle->pszMountPoint[0] = 0;
- return osl_File_E_None;
-
- default:
- break;
- }
-
- return osl_File_E_BUSY;
-}
-
-#endif /* SOLARIS */
-
-/******************************************************************************
- *
- * LINUX FLOPPY FUNCTIONS
- *
- *****************************************************************************/
-
-#if defined(LINUX)
-static oslVolumeDeviceHandle
-osl_isFloppyDrive (const sal_Char* pszPath)
-{
- oslVolumeDeviceHandleImpl* pItem = osl_newVolumeDeviceHandleImpl();
- if (osl_getFloppyMountEntry(pszPath, pItem))
- return (oslVolumeDeviceHandle) pItem;
-
- osl_freeVolumeDeviceHandleImpl (pItem);
- return 0;
-}
-#endif /* LINUX */
-
-#if defined(LINUX)
-static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
-{
- sal_Bool bRet = sal_False;
- oslVolumeDeviceHandleImpl* pItem=0;
- int nRet;
- sal_Char pszCmd[PATH_MAX];
- const sal_Char* pszMountProg = "mount";
- sal_Char* pszSuDo = 0;
- sal_Char* pszTmp = 0;
-
- pszCmd[0] = '\0';
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"In osl_mountFloppy\n");
-#endif
-
- pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
-
- if ( pItem == 0 )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_mountFloppy [pItem == 0]\n");
-#endif
-
- return osl_File_E_INVAL;
- }
-
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_mountFloppy [invalid handle]\n");
-#endif
- return osl_File_E_INVAL;
- }
-
- bRet = osl_isFloppyMounted(pItem);
- if ( bRet == sal_True )
- {
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"detected mounted floppy at '%s'\n",pItem->pszMountPoint);
-#endif
- return osl_File_E_BUSY;
- }
-
- /* mfe: we can't use the mount(2) system call!!! */
- /* even if we are root */
- /* since mtab is not updated!!! */
- /* but we need it to be updated */
- /* some "magic" must be done */
-
-/* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
-/* if ( nRet != 0 ) */
-/* { */
-/* nRet=errno; */
-/* #ifdef DEBUG_OSL_FILE */
-/* perror("mount"); */
-/* #endif */
-/* } */
-
- pszTmp = getenv("SAL_MOUNT_MOUNTPROG");
- if ( pszTmp != 0 )
- {
- pszMountProg=pszTmp;
- }
-
- pszTmp=getenv("SAL_MOUNT_SU_DO");
- if ( pszTmp != 0 )
- {
- pszSuDo=pszTmp;
- }
-
- if ( pszSuDo != 0 )
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s %s %s",pszSuDo,pszMountProg,pItem->pszDevice,pItem->pszMountPoint);
- }
- else
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszMountProg,pItem->pszMountPoint);
- }
-
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"executing '%s'\n",pszCmd);
-#endif
-
- nRet = system(pszCmd);
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"call returned '%i'\n",nRet);
- fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
-#endif
-
-
- switch ( WEXITSTATUS(nRet) )
- {
- case 0:
- nRet=0;
- break;
-
- case 2:
- nRet=EPERM;
- break;
-
- case 4:
- nRet=ENOENT;
- break;
-
- case 8:
- nRet=EINTR;
- break;
-
- case 16:
- nRet=EPERM;
- break;
-
- case 32:
- nRet=EBUSY;
- break;
-
- case 64:
- nRet=EAGAIN;
- break;
-
- default:
- nRet=EBUSY;
- break;
- }
-
- return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
-}
-#endif /* LINUX */
-
-
-#if defined(LINUX)
-static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
-{
- oslVolumeDeviceHandleImpl* pItem=0;
- int nRet=0;
- sal_Char pszCmd[PATH_MAX];
- sal_Char* pszTmp = 0;
- sal_Char* pszSuDo = 0;
- const sal_Char* pszUmountProg = "umount";
-
- pszCmd[0] = '\0';
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"In osl_unmountFloppy\n");
-#endif
-
- pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
-
- if ( pItem == 0 )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_unmountFloppy [pItem==0]\n");
-#endif
- return osl_File_E_INVAL;
- }
-
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_unmountFloppy [invalid handle]\n");
-#endif
- return osl_File_E_INVAL;
- }
-
- /* mfe: we can't use the umount(2) system call!!! */
- /* even if we are root */
- /* since mtab is not updated!!! */
- /* but we need it to be updated */
- /* some "magic" must be done */
-
-/* nRet=umount(pItem->pszDevice); */
-/* if ( nRet != 0 ) */
-/* { */
-/* nRet = errno; */
-
-/* #ifdef DEBUG_OSL_FILE */
-/* perror("mount"); */
-/* #endif */
-/* } */
-
-
- pszTmp = getenv("SAL_MOUNT_UMOUNTPROG");
- if ( pszTmp != 0 )
- {
- pszUmountProg=pszTmp;
- }
-
- pszTmp = getenv("SAL_MOUNT_SU_DO");
- if ( pszTmp != 0 )
- {
- pszSuDo=pszTmp;
- }
-
- if ( pszSuDo != 0 )
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s %s",pszSuDo,pszUmountProg,pItem->pszMountPoint);
- }
- else
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszUmountProg,pItem->pszMountPoint);
- }
-
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"executing '%s'\n",pszCmd);
-#endif
-
- nRet = system(pszCmd);
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"call returned '%i'\n",nRet);
- fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
-#endif
-
- switch ( WEXITSTATUS(nRet) )
- {
- case 0:
- nRet=0;
- break;
-
- default:
- nRet=EBUSY;
- break;
- }
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_unmountFloppy [ok]\n");
-#endif
-
- return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
-
-/* return osl_File_E_None;*/
-}
-
-#endif /* LINUX */
-
-#if defined(LINUX)
-static sal_Bool
-osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
-{
- struct mntent* pMountEnt;
- FILE* pMountTab;
-
- pMountTab = setmntent (MOUNTTAB, "r");
- if (pMountTab == 0)
- return sal_False;
-
- while ((pMountEnt = getmntent(pMountTab)) != 0)
- {
- if ( strncmp(pMountEnt->mnt_dir, pszPath, strlen(pMountEnt->mnt_dir)) == 0
- && strncmp(pMountEnt->mnt_fsname, "/dev/fd", strlen("/dev/fd")) == 0)
- {
- memset(pItem->pszMountPoint, 0, sizeof(pItem->pszMountPoint));
- strncpy(pItem->pszMountPoint, pMountEnt->mnt_dir, sizeof(pItem->pszMountPoint) - 1);
-
- memset(pItem->pszFilePath, 0, sizeof(pItem->pszFilePath));
- strncpy(pItem->pszFilePath, pMountEnt->mnt_dir, sizeof(pItem->pszFilePath) - 1);
-
- memset(pItem->pszDevice, 0, sizeof(pItem->pszDevice));
- strncpy(pItem->pszDevice, pMountEnt->mnt_fsname, sizeof(pItem->pszDevice) - 1);
-
- endmntent (pMountTab);
- return sal_True;
- }
- }
-
- endmntent (pMountTab);
- return sal_False;
-}
-#endif /* LINUX */
-
-#if defined(LINUX)
-static sal_Bool
-osl_isFloppyMounted (oslVolumeDeviceHandleImpl* pDevice)
-{
- oslVolumeDeviceHandleImpl aItem;
-
- if ( osl_getFloppyMountEntry (pDevice->pszMountPoint, &aItem)
- && strcmp (aItem.pszMountPoint, pDevice->pszMountPoint) == 0
- && strcmp (aItem.pszDevice, pDevice->pszDevice) == 0)
- {
- return sal_True;
- }
- return sal_False;
-}
-#endif /* LINUX */
-
-/******************************************************************************
- *
- * IRIX FLOPPY FUNCTIONS
- *
- *****************************************************************************/
-
-#if defined(IRIX)
-static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
-{
- oslVolumeDeviceHandleImpl* pItem = osl_newVolumeDeviceHandleImpl ();
- sal_Bool bRet = sal_False;
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"In osl_isFloppyDrive\n");
-#endif
-
- bRet=osl_getFloppyMountEntry(pszPath,pItem);
-
- if ( bRet == sal_False )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_isFloppyDrive [not a floppy]\n");
-#endif
- rtl_freeMemory(pItem);
- return 0;
- }
-
-
-#ifdef DEBUG_OSL_FILE
- osl_printFloppyHandle(pItem);
-#endif
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_isFloppyDrive [ok]\n");
-#endif
-
- return (oslVolumeDeviceHandle) pItem;
-}
-
-
-static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
-{
- sal_Bool bRet = sal_False;
- oslVolumeDeviceHandleImpl* pItem=0;
- int nRet;
- sal_Char pszCmd[PATH_MAX];
- sal_Char* pszMountProg = "mount";
- sal_Char* pszSuDo = 0;
- sal_Char* pszTmp = 0;
-
- pszCmd[0] = '\0';
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"In osl_mountFloppy\n");
-#endif
-
- pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
-
- if ( pItem == 0 )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_mountFloppy [pItem == 0]\n");
-#endif
-
- return osl_File_E_INVAL;
- }
-
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_mountFloppy [invalid handle]\n");
-#endif
- return osl_File_E_INVAL;
- }
-
- bRet = osl_isFloppyMounted(pItem);
- if ( bRet == sal_True )
- {
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"detected mounted floppy at '%s'\n",pItem->pszMountPoint);
-#endif
- return osl_File_E_BUSY;
- }
-
- /* mfe: we can't use the mount(2) system call!!! */
- /* even if we are root */
- /* since mtab is not updated!!! */
- /* but we need it to be updated */
- /* some "magic" must be done */
-
-/* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
-/* if ( nRet != 0 ) */
-/* { */
-/* nRet=errno; */
-/* #ifdef DEBUG_OSL_FILE */
-/* perror("mount"); */
-/* #endif */
-/* } */
-
- pszTmp = getenv("SAL_MOUNT_MOUNTPROG");
- if ( pszTmp != 0 )
- {
- pszMountProg=pszTmp;
- }
-
- pszTmp=getenv("SAL_MOUNT_SU_DO");
- if ( pszTmp != 0 )
- {
- pszSuDo=pszTmp;
- }
-
- if ( pszSuDo != 0 )
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s %s %s",pszSuDo,pszMountProg,pItem->pszDevice,pItem->pszMountPoint);
- }
- else
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszMountProg,pItem->pszMountPoint);
- }
-
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"executing '%s'\n",pszCmd);
-#endif
-
- nRet = system(pszCmd);
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"call returned '%i'\n",nRet);
- fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
-#endif
-
-
- switch ( WEXITSTATUS(nRet) )
- {
- case 0:
- nRet=0;
- break;
-
- case 2:
- nRet=EPERM;
- break;
-
- case 4:
- nRet=ENOENT;
- break;
-
- case 8:
- nRet=EINTR;
- break;
-
- case 16:
- nRet=EPERM;
- break;
-
- case 32:
- nRet=EBUSY;
- break;
-
- case 64:
- nRet=EAGAIN;
- break;
-
- default:
- nRet=EBUSY;
- break;
- }
-
- return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
-}
-
-static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
-{
- oslVolumeDeviceHandleImpl* pItem=0;
- int nRet=0;
- sal_Char pszCmd[PATH_MAX];
- sal_Char* pszTmp = 0;
- sal_Char* pszSuDo = 0;
- sal_Char* pszUmountProg = "umount";
-
- pszCmd[0] = '\0';
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"In osl_unmountFloppy\n");
-#endif
-
- pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
-
- if ( pItem == 0 )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_unmountFloppy [pItem==0]\n");
-#endif
- return osl_File_E_INVAL;
- }
-
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_unmountFloppy [invalid handle]\n");
-#endif
- return osl_File_E_INVAL;
- }
-
- /* mfe: we can't use the umount(2) system call!!! */
- /* even if we are root */
- /* since mtab is not updated!!! */
- /* but we need it to be updated */
- /* some "magic" must be done */
-
-/* nRet=umount(pItem->pszDevice); */
-/* if ( nRet != 0 ) */
-/* { */
-/* nRet = errno; */
-
-/* #ifdef DEBUG_OSL_FILE */
-/* perror("mount"); */
-/* #endif */
-/* } */
-
-
- pszTmp = getenv("SAL_MOUNT_UMOUNTPROG");
- if ( pszTmp != 0 )
- {
- pszUmountProg=pszTmp;
- }
-
- pszTmp = getenv("SAL_MOUNT_SU_DO");
- if ( pszTmp != 0 )
- {
- pszSuDo=pszTmp;
- }
-
- if ( pszSuDo != 0 )
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s %s",pszSuDo,pszUmountProg,pItem->pszMountPoint);
- }
- else
- {
- snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszUmountProg,pItem->pszMountPoint);
- }
-
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"executing '%s'\n",pszCmd);
-#endif
-
- nRet = system(pszCmd);
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"call returned '%i'\n",nRet);
- fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
-#endif
-
- switch ( WEXITSTATUS(nRet) )
- {
- case 0:
- nRet=0;
- break;
-
- default:
- nRet=EBUSY;
- break;
- }
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_unmountFloppy [ok]\n");
-#endif
-
- return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
-
-/* return osl_File_E_None;*/
-}
-
-static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
-{
- struct mntent* pMountEnt=0;
- sal_Char buffer[PATH_MAX];
- FILE* mntfile=0;
- int nRet=0;
-
- buffer[0] = '\0';
-
- mntfile = setmntent(MOUNTTAB,"r");
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"In osl_getFloppyMountEntry\n");
-#endif
-
- memset(buffer, 0, sizeof(buffer));
- strncpy(buffer, pszPath, sizeof(buffer) - 1);
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"Checking mount of %s\n",buffer);
-#endif
-
-
- if ( mntfile == 0 )
- {
- nRet=errno;
-#ifdef DEBUG_OSL_FILE
- perror("mounttab");
-#endif
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_getFloppyMountEntry [mntfile]\n");
-#endif
- return sal_False;
- }
-
- pMountEnt=getmntent(mntfile);
- while ( pMountEnt != 0 )
- {
-#ifdef DEBUG_OSL_FILE
-/* fprintf(stderr,"mnt_fsname : %s\n",pMountEnt->mnt_fsname); */
-/* fprintf(stderr,"mnt_dir : %s\n",pMountEnt->mnt_dir); */
-/* fprintf(stderr,"mnt_type : %s\n",pMountEnt->mnt_type);*/
-#endif
- if ( strcmp(pMountEnt->mnt_dir,buffer) == 0 &&
- strncmp(pMountEnt->mnt_fsname,"/dev/fd",strlen("/dev/fd")) == 0 )
- {
-
- memset(pItem->pszMountPoint, 0, sizeof(pItem->pszMountPoint));
- strncpy(pItem->pszMountPoint, pMountEnt->mnt_dir, sizeof(pItem->pszMountPoint) - 1);
-
- memset(pItem->pszFilePath, 0, sizeof(pItem->pszFilePath));
- strncpy(pItem->pszFilePath, pMountEnt->mnt_dir, sizeof(pItem->pszFilePath) - 1);
-
- memset(pItem->pszDevice, 0, sizeof(pItem->pszDevice));
- strncpy(pItem->pszDevice, pMountEnt->mnt_fsname, sizeof(pItem->pszDevice) - 1);
-
- fclose(mntfile);
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"Mount Point found '%s'\n",pItem->pszMountPoint);
-#endif
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_getFloppyMountEntry [found]\n");
-#endif
- return sal_True;
- }
-#ifdef DEBUG_OSL_FILE
-/* fprintf(stderr,"=================\n");*/
-#endif
- pMountEnt=getmntent(mntfile);
- }
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_getFloppyMountEntry [not found]\n");
-#endif
-
- fclose(mntfile);
- return sal_False;
-}
-
-static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
-{
- sal_Char buffer[PATH_MAX];
- oslVolumeDeviceHandleImpl* pItem=0;
- sal_Bool bRet=0;
-
- buffer[0] = '\0';
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"In osl_isFloppyMounted\n");
-#endif
-
- pItem = osl_newVolumeDeviceHandleImpl ();
- if ( pItem == 0 )
- return osl_File_E_NOMEM;
-
- memset(buffer, 0, sizeof(buffer));
- strncpy(buffer, pDevice->pszMountPoint, sizeof(buffer) - 1);
-
-#ifdef DEBUG_OSL_FILE
- fprintf(stderr,"Checking mount of %s\n",buffer);
-#endif
-
- bRet = osl_getFloppyMountEntry(buffer,pItem);
-
- if ( bRet == sal_False )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_isFloppyMounted [not mounted]\n");
-#endif
- return sal_False;
- }
-
- if (strcmp(pItem->pszMountPoint, pDevice->pszMountPoint) == 0 &&
- strcmp(pItem->pszDevice,pDevice->pszDevice) == 0)
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_isFloppyMounted [is mounted]\n");
-#endif
- rtl_freeMemory(pItem);
- return sal_True;
- }
-
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Out osl_isFloppyMounted [may be EBUSY]\n");
-#endif
-
- rtl_freeMemory(pItem);
- return sal_False;
-}
-#endif /* IRIX */
-
-
-/* NetBSD floppy functions have to be added here. Until we have done that,
- * we use the MACOSX definitions for nonexistent floppy.
- * */
-
-/******************************************************************************
- *
- * MAC OS X FLOPPY FUNCTIONS
- *
- *****************************************************************************/
-
-#if (defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
-static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
-{
- return NULL;
-}
-#endif /* MACOSX */
-
-#if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
-static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
-{
- return osl_File_E_BUSY;
-}
-#endif /* MACOSX */
-
-#if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
-static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
-{
- return osl_File_E_BUSY;
-}
-#endif /* MACOSX */
-
-#if ( defined(NETBSD) || defined(FREEBSD) )
-static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
-{
- return sal_False;
-}
-#endif /* NETBSD || FREEBSD */
-
-#if ( defined(NETBSD) || defined(FREEBSD) )
-static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
-{
- return sal_False;
-}
-#endif /* NETBSD || FREEBSD */
-
-
-#ifdef DEBUG_OSL_FILE
-static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
-{
- if (pItem == 0 )
- {
- fprintf(stderr,"NULL Handle\n");
- return;
- }
- if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
- {
-#ifdef TRACE_OSL_FILE
- fprintf(stderr,"Invalid Handle]\n");
-#endif
- return;
- }
-
-
- fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
- fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
- fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
-
- return;
-}
-#endif
-
diff --git a/sal/osl/unx/file_impl.hxx b/sal/osl/unx/file_impl.hxx
index 7a379125c..a1b0da6f9 100644
--- a/sal/osl/unx/file_impl.hxx
+++ b/sal/osl/unx/file_impl.hxx
@@ -28,21 +28,30 @@
*
************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-typedef struct
+#ifndef INCLUDED_FILE_IMPL_HXX
+#define INCLUDED_FILE_IMPL_HXX
+
+#include "osl/file.h"
+#include <stddef.h>
+
+struct DirectoryItem_Impl
{
- rtl_uString* ustrFilePath; /* holds native file name */
- unsigned char DType;
- bool bHasType;
- sal_uInt32 RefCount;
-} oslDirectoryItemImpl;
-
- oslDirectoryItemImpl* oslDirectoryItemImpl_CreateNew( rtl_uString* _ustrFilePath, bool _bHasDType, unsigned char _DType=0 );
- void oslDirectoryItemImpl_Destroy( oslDirectoryItemImpl* pItem );
- void oslDirectoryItemImpl_acquire( oslDirectoryItemImpl* pItem );
- void oslDirectoryItemImpl_release( oslDirectoryItemImpl* pItem );
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
+ sal_Int32 m_RefCount;
+
+ rtl_uString * m_ustrFilePath; /* holds native file name */
+ unsigned char m_DType;
+
+ explicit DirectoryItem_Impl(
+ rtl_uString * ustrFilePath, unsigned char DType = 0);
+ ~DirectoryItem_Impl();
+
+ static void * operator new(size_t n);
+ static void operator delete (void * p, size_t);
+
+ void acquire(); /* @see osl_acquireDirectoryItem() */
+ void release(); /* @see osl_releaseDirectoryItem() */
+
+ oslFileType getFileType() const;
+};
+
+#endif /* INCLUDED_FILE_IMPL_HXX */
diff --git a/sal/osl/unx/file_misc.cxx b/sal/osl/unx/file_misc.cxx
new file mode 100644
index 000000000..a04d4b4c9
--- /dev/null
+++ b/sal/osl/unx/file_misc.cxx
@@ -0,0 +1,1084 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "osl/file.hxx"
+
+#include "osl/diagnose.h"
+#include "osl/thread.h"
+#include "rtl/alloc.h"
+
+#include "system.h"
+#include "file_impl.hxx"
+#include "file_error_transl.h"
+#include "file_path_helper.hxx"
+#include "file_url.h"
+#include "uunxapi.hxx"
+
+#include <sys/types.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+/************************************************************************
+ * ToDo
+ *
+ * - Fix: check for corresponding struct sizes in exported functions
+ * - check size/use of oslDirectory
+ * - check size/use of oslDirectoryItem
+ ***********************************************************************/
+/******************************************************************************
+ *
+ * Data Type Definition
+ *
+ ******************************************************************************/
+
+typedef struct
+{
+ rtl_uString* ustrPath; /* holds native directory path */
+ DIR* pDirStruct;
+} oslDirectoryImpl;
+
+#if 0
+/* FIXME: reintroducing this may save some extra bytes per Item */
+typedef struct
+{
+ rtl_uString* ustrFileName; /* holds native file name */
+ rtl_uString* ustrDirPath; /* holds native dir path */
+ sal_uInt32 RefCount;
+} oslDirectoryItemImpl;
+#endif
+
+DirectoryItem_Impl::DirectoryItem_Impl(
+ rtl_uString * ustrFilePath, unsigned char DType)
+ : m_RefCount (1),
+ m_ustrFilePath (ustrFilePath),
+ m_DType (DType)
+{
+ if (m_ustrFilePath != 0)
+ rtl_uString_acquire(m_ustrFilePath);
+}
+DirectoryItem_Impl::~DirectoryItem_Impl()
+{
+ if (m_ustrFilePath != 0)
+ rtl_uString_release(m_ustrFilePath);
+}
+
+void * DirectoryItem_Impl::operator new(size_t n)
+{
+ return rtl_allocateMemory(n);
+}
+void DirectoryItem_Impl::operator delete(void * p, size_t)
+{
+ rtl_freeMemory(p);
+}
+
+void DirectoryItem_Impl::acquire()
+{
+ ++m_RefCount;
+}
+void DirectoryItem_Impl::release()
+{
+ if (0 == --m_RefCount)
+ delete this;
+}
+
+oslFileType DirectoryItem_Impl::getFileType() const
+{
+ switch (m_DType)
+ {
+#ifdef _DIRENT_HAVE_D_TYPE
+ case DT_LNK:
+ return osl_File_Type_Link;
+ case DT_DIR:
+ return osl_File_Type_Directory;
+ case DT_REG:
+ return osl_File_Type_Regular;
+ case DT_FIFO:
+ return osl_File_Type_Fifo;
+ case DT_SOCK:
+ return osl_File_Type_Socket;
+ case DT_CHR:
+ case DT_BLK:
+ return osl_File_Type_Special;
+#endif /* _DIRENT_HAVE_D_TYPE */
+ default:
+ break;
+ }
+ return osl_File_Type_Unknown;
+}
+
+/******************************************************************************
+ *
+ * C-String Function Declarations
+ *
+ *****************************************************************************/
+
+static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
+static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
+
+/*******************************************************************
+ * osl_openDirectory
+ ******************************************************************/
+
+oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
+{
+ rtl_uString* ustrSystemPath = NULL;
+ oslFileError eRet;
+
+ char path[PATH_MAX];
+
+ if ((0 == ustrDirectoryURL) || (0 == ustrDirectoryURL->length) || (0 == pDirectory))
+ return osl_File_E_INVAL;
+
+ /* convert file URL to system path */
+ eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False);
+
+ if( osl_File_E_None != eRet )
+ return eRet;
+
+ osl_systemPathRemoveSeparator(ustrSystemPath);
+
+ /* convert unicode path to text */
+ if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length )
+#ifdef MACOSX
+ && macxp_resolveAlias( path, PATH_MAX ) == 0
+#endif /* MACOSX */
+ )
+ {
+ /* open directory */
+ DIR *pdir = opendir( path );
+
+ if( pdir )
+ {
+ /* create and initialize impl structure */
+ oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) rtl_allocateMemory( sizeof(oslDirectoryImpl) );
+
+ if( pDirImpl )
+ {
+ pDirImpl->pDirStruct = pdir;
+ pDirImpl->ustrPath = ustrSystemPath;
+
+ *pDirectory = (oslDirectory) pDirImpl;
+ return osl_File_E_None;
+ }
+ else
+ {
+ errno = ENOMEM;
+ closedir( pdir );
+ }
+ }
+ else
+ {
+#ifdef DEBUG_OSL_FILE
+ perror ("osl_openDirectory"); fprintf (stderr, path);
+#endif
+ }
+ }
+
+ rtl_uString_release( ustrSystemPath );
+
+ return oslTranslateFileError(OSL_FET_ERROR, errno);
+}
+
+/****************************************************************************/
+/* osl_closeDirectory */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
+{
+ oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) Directory;
+ oslFileError err = osl_File_E_None;
+
+ OSL_ASSERT( Directory );
+
+ if( NULL == pDirImpl )
+ return osl_File_E_INVAL;
+
+ /* close directory */
+ if( closedir( pDirImpl->pDirStruct ) )
+ {
+ err = oslTranslateFileError(OSL_FET_ERROR, errno);
+ }
+
+ /* cleanup members */
+ rtl_uString_release( pDirImpl->ustrPath );
+
+ rtl_freeMemory( pDirImpl );
+
+ return err;
+}
+
+/**********************************************
+ * osl_readdir_impl_
+ *
+ * readdir wrapper, filters out "." and ".."
+ * on request
+ *********************************************/
+
+static struct dirent* osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
+{
+ struct dirent* pdirent;
+
+ while ((pdirent = readdir(pdir)) != NULL)
+ {
+ if (bFilterLocalAndParentDir &&
+ ((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
+ continue;
+ else
+ break;
+ }
+
+ return pdirent;
+}
+
+/****************************************************************************
+ * osl_getNextDirectoryItem
+ ***************************************************************************/
+
+oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, sal_uInt32 /*uHint*/)
+{
+ oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*)Directory;
+ rtl_uString* ustrFileName = NULL;
+ rtl_uString* ustrFilePath = NULL;
+ struct dirent* pEntry;
+
+ OSL_ASSERT(Directory);
+ OSL_ASSERT(pItem);
+
+ if ((NULL == Directory) || (NULL == pItem))
+ return osl_File_E_INVAL;
+
+ pEntry = osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
+
+ if (NULL == pEntry)
+ return osl_File_E_NOENT;
+
+
+#if defined(MACOSX)
+
+ // convert decomposed filename to precomposed unicode
+ char composed_name[BUFSIZ];
+ CFMutableStringRef strRef = CFStringCreateMutable (NULL, 0 );
+ CFStringAppendCString( strRef, pEntry->d_name, kCFStringEncodingUTF8 ); //UTF8 is default on Mac OSX
+ CFStringNormalize( strRef, kCFStringNormalizationFormC );
+ CFStringGetCString( strRef, composed_name, BUFSIZ, kCFStringEncodingUTF8 );
+ CFRelease( strRef );
+ rtl_string2UString( &ustrFileName, composed_name, strlen( composed_name),
+ osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
+
+#else // not MACOSX
+ /* convert file name to unicode */
+ rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
+ osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
+ OSL_ASSERT(ustrFileName != 0);
+
+#endif
+
+ osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &ustrFilePath);
+ rtl_uString_release( ustrFileName );
+
+ DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(*pItem);
+ if (0 != pImpl)
+ {
+ pImpl->release(), pImpl = 0;
+ }
+#ifdef _DIRENT_HAVE_D_TYPE
+ pImpl = new DirectoryItem_Impl(ustrFilePath, pEntry->d_type);
+#else
+ pImpl = new DirectoryItem_Impl(ustrFilePath);
+#endif /* _DIRENT_HAVE_D_TYPE */
+ *pItem = pImpl;
+ rtl_uString_release( ustrFilePath );
+
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_getDirectoryItem */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
+{
+ rtl_uString* ustrSystemPath = NULL;
+ oslFileError osl_error = osl_File_E_INVAL;
+
+ OSL_ASSERT(ustrFileURL);
+ OSL_ASSERT(pItem);
+
+ if (0 == ustrFileURL->length || NULL == pItem)
+ return osl_File_E_INVAL;
+
+ osl_error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &ustrSystemPath, sal_False);
+ if (osl_File_E_None != osl_error)
+ return osl_error;
+
+ osl_systemPathRemoveSeparator(ustrSystemPath);
+
+ if (-1 == access_u(ustrSystemPath, F_OK))
+ {
+ osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
+ }
+ else
+ {
+ *pItem = new DirectoryItem_Impl(ustrSystemPath);
+ }
+ rtl_uString_release(ustrSystemPath);
+
+ return osl_error;
+}
+
+
+/****************************************************************************/
+/* osl_acquireDirectoryItem */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_acquireDirectoryItem( oslDirectoryItem Item )
+{
+ DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item);
+ if (0 == pImpl)
+ return osl_File_E_INVAL;
+
+ pImpl->acquire();
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_releaseDirectoryItem */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item )
+{
+ DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item);
+ if (0 == pImpl)
+ return osl_File_E_INVAL;
+
+ pImpl->release();
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_createDirectory */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_createDirectory( rtl_uString* ustrDirectoryURL )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrDirectoryURL );
+
+ /* convert directory url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return osl_psz_createDirectory( path );
+}
+
+/****************************************************************************/
+/* osl_removeDirectory */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_removeDirectory( rtl_uString* ustrDirectoryURL )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrDirectoryURL );
+
+ /* convert directory url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return osl_psz_removeDirectory( path );
+}
+
+/*****************************************
+ * osl_psz_createDirectory
+ ****************************************/
+
+static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
+{
+ int nRet=0;
+ int mode = S_IRWXU | S_IRWXG | S_IRWXO;
+
+ nRet = mkdir(pszPath,mode);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_psz_removeDirectory
+ ****************************************/
+
+static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
+{
+ int nRet=0;
+
+ nRet = rmdir(pszPath);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_createDirectoryPath */
+/****************************************************************************/
+
+static int path_make_parent(sal_Unicode* path)
+{
+ int i = rtl_ustr_lastIndexOfChar(path, '/');
+
+ if (i > 0)
+ {
+ *(path + i) = 0;
+ return i;
+ }
+ else
+ return 0;
+}
+
+static int create_dir_with_callback(
+ sal_Unicode* directory_path,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ int mode = S_IRWXU | S_IRWXG | S_IRWXO;
+
+ if (osl::mkdir(directory_path, mode) == 0)
+ {
+ if (aDirectoryCreationCallbackFunc)
+ {
+ rtl::OUString url;
+ osl::FileBase::getFileURLFromSystemPath(directory_path, url);
+ aDirectoryCreationCallbackFunc(pData, url.pData);
+ }
+ return 0;
+ }
+ return errno;
+}
+
+static oslFileError create_dir_recursively_(
+ sal_Unicode* dir_path,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \
+ "Path must not end with a slash");
+
+ int native_err = create_dir_with_callback(
+ dir_path, aDirectoryCreationCallbackFunc, pData);
+
+ if (native_err == 0)
+ return osl_File_E_None;
+
+ if (native_err != ENOENT)
+ return oslTranslateFileError(OSL_FET_ERROR, native_err);
+
+ // we step back until '/a_dir' at maximum because
+ // we should get an error unequal ENOENT when
+ // we try to create 'a_dir' at '/' and would so
+ // return before
+ int pos = path_make_parent(dir_path);
+
+ oslFileError osl_error = create_dir_recursively_(
+ dir_path, aDirectoryCreationCallbackFunc, pData);
+
+ if (osl_File_E_None != osl_error)
+ return osl_error;
+
+ dir_path[pos] = '/';
+
+ return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
+}
+
+oslFileError SAL_CALL osl_createDirectoryPath(
+ rtl_uString* aDirectoryUrl,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ if (aDirectoryUrl == NULL)
+ return osl_File_E_INVAL;
+
+ rtl::OUString sys_path;
+ oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
+ aDirectoryUrl, &sys_path.pData, sal_False);
+
+ if (osl_error != osl_File_E_None)
+ return osl_error;
+
+ osl::systemPathRemoveSeparator(sys_path);
+
+ // const_cast because sys_path is a local copy which we want to modify inplace instead of
+ // coyp it into another buffer on the heap again
+ return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
+}
+
+/******************************************************************************
+ *
+ * C-String Function Declarations
+ *
+ *****************************************************************************/
+
+static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
+static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
+static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
+
+
+/******************************************************************************
+ *
+ * Static Module Utility Function Declarations
+ *
+ *****************************************************************************/
+
+static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
+static oslFileError oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
+static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
+static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
+static oslFileError oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
+
+/****************************************************************************/
+/* osl_moveFile */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
+{
+ char srcPath[PATH_MAX];
+ char destPath[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrFileURL );
+ OSL_ASSERT( ustrDestURL );
+
+ /* convert source url to system path */
+ eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ /* convert destination url to system path */
+ eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return oslDoMoveFile( srcPath, destPath );
+}
+
+/****************************************************************************/
+/* osl_copyFile */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
+{
+ char srcPath[PATH_MAX];
+ char destPath[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrFileURL );
+ OSL_ASSERT( ustrDestURL );
+
+ /* convert source url to system path */
+ eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ /* convert destination url to system path */
+ eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return osl_psz_copyFile( srcPath, destPath );
+}
+
+/****************************************************************************/
+/* osl_removeFile */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_removeFile( rtl_uString* ustrFileURL )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrFileURL );
+
+ /* convert file url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return osl_psz_removeFile( path );
+}
+
+/******************************************************************************
+ *
+ * Utility Functions
+ *
+ *****************************************************************************/
+
+/*****************************************
+ * oslDoMoveFile
+ ****************************************/
+
+static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
+{
+ oslFileError tErr=osl_File_E_invalidError;
+
+ tErr = osl_psz_moveFile(pszPath,pszDestPath);
+ if ( tErr == osl_File_E_None )
+ {
+ return tErr;
+ }
+
+ if ( tErr != osl_File_E_XDEV )
+ {
+ return tErr;
+ }
+
+ tErr=osl_psz_copyFile(pszPath,pszDestPath);
+
+ if ( tErr != osl_File_E_None )
+ {
+ oslFileError tErrRemove;
+ tErrRemove=osl_psz_removeFile(pszDestPath);
+ return tErr;
+ }
+
+ tErr=osl_psz_removeFile(pszPath);
+
+ return tErr;
+}
+
+/*****************************************
+ * osl_psz_removeFile
+ ****************************************/
+static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
+{
+ int nRet=0;
+ struct stat aStat;
+
+ nRet = lstat(pszPath,&aStat);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ if ( S_ISDIR(aStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+
+ nRet = unlink(pszPath);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_psz_moveFile
+ ****************************************/
+
+static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
+{
+
+ int nRet = 0;
+
+ nRet = rename(pszPath,pszDestPath);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_psz_copyFile
+ ****************************************/
+
+static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
+{
+ time_t nAcTime=0;
+ time_t nModTime=0;
+ uid_t nUID=0;
+ gid_t nGID=0;
+ int nRet=0;
+ mode_t nMode=0;
+ struct stat aFileStat;
+ oslFileError tErr=osl_File_E_invalidError;
+ size_t nSourceSize=0;
+ int DestFileExists=1;
+
+ /* mfe: does the source file really exists? */
+ nRet = lstat(pszPath,&aFileStat);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ /* mfe: we do only copy files here! */
+ if ( S_ISDIR(aFileStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+
+ nSourceSize=(size_t)aFileStat.st_size;
+ nMode=aFileStat.st_mode;
+ nAcTime=aFileStat.st_atime;
+ nModTime=aFileStat.st_mtime;
+ nUID=aFileStat.st_uid;
+ nGID=aFileStat.st_gid;
+
+ nRet = stat(pszDestPath,&aFileStat);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+
+ if ( nRet == ENOENT )
+ {
+ DestFileExists=0;
+ }
+/* return oslTranslateFileError(nRet);*/
+ }
+
+ /* mfe: the destination file must not be a directory! */
+ if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+ else
+ {
+ /* mfe: file does not exists or is no dir */
+ }
+
+ tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
+
+ if ( tErr != osl_File_E_None )
+ {
+ return tErr;
+ }
+
+ /*
+ * mfe: ignore return code
+ * since only the success of the copy is
+ * important
+ */
+ oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
+
+ return tErr;
+}
+
+
+/******************************************************************************
+ *
+ * Utility Functions
+ *
+ *****************************************************************************/
+
+/*****************************************
+ * oslDoCopy
+ ****************************************/
+
+#define TMP_DEST_FILE_EXTENSION ".osl-tmp"
+
+static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
+{
+ int nRet=0;
+ sal_Char pszTmpDestFile[PATH_MAX];
+ size_t size_tmp_dest_buff = sizeof(pszTmpDestFile);
+
+ /* Quick fix for #106048, the whole copy file function seems
+ to be erroneous anyway and needs to be rewritten.
+ Besides osl_copyFile is currently not used from OO/SO code.
+ */
+ memset(pszTmpDestFile, 0, size_tmp_dest_buff);
+
+ if ( DestFileExists )
+ {
+ strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
+
+ if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION)) >= size_tmp_dest_buff)
+ return osl_File_E_NAMETOOLONG;
+
+ strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION, strlen(TMP_DEST_FILE_EXTENSION));
+
+ /* FIXME: what if pszTmpDestFile already exists? */
+ /* with getcanonical??? */
+ nRet=rename(pszDestFileName,pszTmpDestFile);
+ }
+
+ /* mfe: should be S_ISREG */
+ if ( !S_ISLNK(nMode) )
+ {
+ /* copy SourceFile to DestFile */
+ nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
+ }
+ /* mfe: OK redundant at the moment */
+ else if ( S_ISLNK(nMode) )
+ {
+ nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
+ }
+ else
+ {
+ /* mfe: what to do here? */
+ nRet=ENOSYS;
+ }
+
+ if ( nRet > 0 && DestFileExists == 1 )
+ {
+ unlink(pszDestFileName);
+ rename(pszTmpDestFile,pszDestFileName);
+ }
+
+ if ( nRet > 0 )
+ {
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ if ( DestFileExists == 1 )
+ {
+ unlink(pszTmpDestFile);
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * oslChangeFileModes
+ ****************************************/
+
+static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
+{
+ int nRet=0;
+ struct utimbuf aTimeBuffer;
+
+ nRet = chmod(pszFileName,nMode);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ aTimeBuffer.actime=nAcTime;
+ aTimeBuffer.modtime=nModTime;
+ nRet=utime(pszFileName,&aTimeBuffer);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ if ( nUID != getuid() )
+ {
+ nUID=getuid();
+ }
+
+ nRet=chown(pszFileName,nUID,nGID);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+
+ /* mfe: do not return an error here! */
+ /* return oslTranslateFileError(nRet);*/
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * oslDoCopyLink
+ ****************************************/
+
+static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
+{
+ int nRet=0;
+
+ /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
+ /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
+ sal_Char pszLinkContent[PATH_MAX];
+
+ pszLinkContent[0] = '\0';
+
+ nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return nRet;
+ }
+ else
+ pszLinkContent[ nRet ] = 0;
+
+ nRet = symlink(pszLinkContent,pszDestFileName);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return nRet;
+ }
+
+ return 0;
+}
+
+/*****************************************
+ * oslDoCopyFile
+ ****************************************/
+
+static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
+{
+ int SourceFileFD=0;
+ int DestFileFD=0;
+ int nRet=0;
+ void* pSourceFile=0;
+
+ SourceFileFD=open(pszSourceFileName,O_RDONLY);
+ if ( SourceFileFD < 0 )
+ {
+ nRet=errno;
+ return nRet;
+ }
+
+ DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT, mode);
+
+ if ( DestFileFD < 0 )
+ {
+ nRet=errno;
+ close(SourceFileFD);
+ return nRet;
+ }
+
+ /* HACK: because memory mapping fails on various
+ platforms if the size of the source file is 0 byte */
+ if (0 == nSourceSize)
+ {
+ close(SourceFileFD);
+ close(DestFileFD);
+ return 0;
+ }
+
+ /* FIXME doCopy: fall back code for systems not having mmap */
+ /* mmap file -- open dest file -- write once -- fsync it */
+ pSourceFile=mmap(0,nSourceSize,PROT_READ,MAP_PRIVATE,SourceFileFD,0);
+
+ if ( pSourceFile == MAP_FAILED )
+ {
+ /* it's important to set nRet before the hack
+ otherwise errno may be changed by lstat */
+ nRet = errno;
+ close(SourceFileFD);
+ close(DestFileFD);
+
+ return nRet;
+ }
+
+ nRet = write(DestFileFD,pSourceFile,nSourceSize);
+
+ /* #112584# if 'write' could not write the requested number of bytes
+ we have to fail of course; because it's not exactly specified if 'write'
+ sets errno if less than requested byte could be written we set nRet
+ explicitly to ENOSPC */
+ if ((nRet < 0) || (nRet != sal::static_int_cast< int >(nSourceSize)))
+ {
+ if (nRet < 0)
+ nRet = errno;
+ else
+ nRet = ENOSPC;
+
+ close(SourceFileFD);
+ close(DestFileFD);
+ munmap((char*)pSourceFile,nSourceSize);
+ return nRet;
+ }
+
+ nRet = munmap((char*)pSourceFile,nSourceSize);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ close(SourceFileFD);
+ close(DestFileFD);
+ return nRet;
+ }
+
+ close(SourceFileFD);
+
+ // Removed call to 'fsync' again (#112584#) and instead
+ // evaluate the return value of 'close' in order to detect
+ // and report ENOSPC and other erronous conditions on close
+ if (close(DestFileFD) == -1)
+ return errno;
+ else
+ return 0;
+}
diff --git a/sal/osl/unx/file_stat.cxx b/sal/osl/unx/file_stat.cxx
index b26e89882..63f876ce8 100644
--- a/sal/osl/unx/file_stat.cxx
+++ b/sal/osl/unx/file_stat.cxx
@@ -31,39 +31,20 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"
-#ifndef _TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifndef _LIMITS_H
-#include <limits.h>
-#endif
-
-#ifndef _UNISTD_H
-#include <unistd.h>
-#endif
+#include "osl/file.h"
-#ifndef _DIRENT_H
+#include "system.h"
+#include <sys/types.h>
#include <dirent.h>
-#endif
-
-#include <osl/file.h>
-
-#ifndef _ERRNO_H
#include <errno.h>
-#endif
-
-#include <rtl/string.hxx>
-
-#ifndef _OSL_UUNXAPI_H_
-#include "uunxapi.hxx"
-#endif
-#include "file_path_helper.hxx"
-#include "file_error_transl.h"
+#include <limits.h>
+#include <unistd.h>
-#ifdef _DIRENT_HAVE_D_TYPE
#include "file_impl.hxx"
-#endif
+#include "file_error_transl.h"
+#include "file_path_helper.hxx"
+#include "file_url.h"
+#include "uunxapi.hxx"
namespace /* private */
{
@@ -231,19 +212,10 @@ namespace /* private */
/* we only need to call stat or lstat if one of the
following flags is set */
-#ifdef _DIRENT_HAVE_D_TYPE
- inline bool is_stat_call_necessary(sal_uInt32 field_mask, oslDirectoryItemImpl *pImpl)
-#else
- inline bool is_stat_call_necessary(sal_uInt32 field_mask)
-#endif
+ inline bool is_stat_call_necessary(sal_uInt32 field_mask, oslFileType file_type = osl_File_Type_Unknown)
{
return (
-/* on linux the dirent might have d_type */
-#ifdef _DIRENT_HAVE_D_TYPE
- ((field_mask & osl_FileStatus_Mask_Type) && (!pImpl->bHasType || pImpl->DType == DT_UNKNOWN)) ||
-#else
- (field_mask & osl_FileStatus_Mask_Type) ||
-#endif
+ ((field_mask & osl_FileStatus_Mask_Type) && (file_type == osl_File_Type_Unknown)) ||
(field_mask & osl_FileStatus_Mask_Attributes) ||
(field_mask & osl_FileStatus_Mask_CreationTime) ||
(field_mask & osl_FileStatus_Mask_AccessTime) ||
@@ -267,24 +239,18 @@ namespace /* private */
return osl_File_E_None;
}
- inline oslFileError setup_osl_getFileStatus(oslDirectoryItem Item, oslFileStatus* pStat, rtl::OUString& file_path)
+ inline oslFileError setup_osl_getFileStatus(
+ DirectoryItem_Impl * pImpl, oslFileStatus* pStat, rtl::OUString& file_path)
{
- if ((NULL == Item) || (NULL == pStat))
+ if ((NULL == pImpl) || (NULL == pStat))
return osl_File_E_INVAL;
-#ifdef _DIRENT_HAVE_D_TYPE
- file_path = rtl::OUString(reinterpret_cast<rtl_uString*>(((oslDirectoryItemImpl* ) Item)->ustrFilePath));
-#else
- file_path = rtl::OUString(reinterpret_cast<rtl_uString*>(Item));
-#endif
-
+ file_path = rtl::OUString(pImpl->m_ustrFilePath);
OSL_ASSERT(file_path.getLength() > 0);
-
if (file_path.getLength() <= 0)
return osl_File_E_INVAL;
pStat->uValidFields = 0;
-
return osl_File_E_None;
}
@@ -297,8 +263,10 @@ namespace /* private */
oslFileError SAL_CALL osl_getFileStatus(oslDirectoryItem Item, oslFileStatus* pStat, sal_uInt32 uFieldMask)
{
+ DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item);
+
rtl::OUString file_path;
- oslFileError osl_error = setup_osl_getFileStatus(Item, pStat, file_path);
+ oslFileError osl_error = setup_osl_getFileStatus(pImpl, pStat, file_path);
if (osl_File_E_None != osl_error)
return osl_error;
@@ -308,13 +276,7 @@ oslFileError SAL_CALL osl_getFileStatus(oslDirectoryItem Item, oslFileStatus* pS
struct stat file_stat;
#endif
-#ifdef _DIRENT_HAVE_D_TYPE
- oslDirectoryItemImpl* pImpl = (oslDirectoryItemImpl*) Item;
- bool bStatNeeded = is_stat_call_necessary(uFieldMask, pImpl);
-#else
- bool bStatNeeded = is_stat_call_necessary(uFieldMask);
-#endif
-
+ bool bStatNeeded = is_stat_call_necessary(uFieldMask, pImpl->getFileType());
if (bStatNeeded && (0 != osl::lstat(file_path, file_stat)))
return oslTranslateFileError(OSL_FET_ERROR, errno);
@@ -338,37 +300,10 @@ oslFileError SAL_CALL osl_getFileStatus(oslDirectoryItem Item, oslFileStatus* pS
#ifdef _DIRENT_HAVE_D_TYPE
else if (uFieldMask & osl_FileStatus_Mask_Type)
{
- OSL_ASSERT(pImpl->bHasType);
-
- switch(pImpl->DType)
- {
- case DT_LNK:
- pStat->eType = osl_File_Type_Link;
- break;
- case DT_DIR:
- pStat->eType = osl_File_Type_Directory;
- break;
- case DT_REG:
- pStat->eType = osl_File_Type_Regular;
- break;
- case DT_FIFO:
- pStat->eType = osl_File_Type_Fifo;
- break;
- case DT_SOCK:
- pStat->eType = osl_File_Type_Socket;
- break;
- case DT_CHR:
- case DT_BLK:
- pStat->eType = osl_File_Type_Special;
- break;
- default:
- OSL_ASSERT(0);
- pStat->eType = osl_File_Type_Unknown;
- }
-
- pStat->uValidFields |= osl_FileStatus_Mask_Type;
+ pStat->eType = pImpl->getFileType();
+ pStat->uValidFields |= osl_FileStatus_Mask_Type;
}
-#endif
+#endif /* _DIRENT_HAVE_D_TYPE */
if (uFieldMask & osl_FileStatus_Mask_FileURL)
{
@@ -386,3 +321,175 @@ oslFileError SAL_CALL osl_getFileStatus(oslDirectoryItem Item, oslFileStatus* pS
return osl_File_E_None;
}
+/****************************************************************************/
+/* osl_setFileAttributes */
+/****************************************************************************/
+
+static oslFileError osl_psz_setFileAttributes( const sal_Char* pszFilePath, sal_uInt64 uAttributes )
+{
+ oslFileError osl_error = osl_File_E_None;
+ mode_t nNewMode = 0;
+
+ OSL_ENSURE(!(osl_File_Attribute_Hidden & uAttributes), "osl_File_Attribute_Hidden doesn't work under Unix");
+
+ if (uAttributes & osl_File_Attribute_OwnRead)
+ nNewMode |= S_IRUSR;
+
+ if (uAttributes & osl_File_Attribute_OwnWrite)
+ nNewMode|=S_IWUSR;
+
+ if (uAttributes & osl_File_Attribute_OwnExe)
+ nNewMode|=S_IXUSR;
+
+ if (uAttributes & osl_File_Attribute_GrpRead)
+ nNewMode|=S_IRGRP;
+
+ if (uAttributes & osl_File_Attribute_GrpWrite)
+ nNewMode|=S_IWGRP;
+
+ if (uAttributes & osl_File_Attribute_GrpExe)
+ nNewMode|=S_IXGRP;
+
+ if (uAttributes & osl_File_Attribute_OthRead)
+ nNewMode|=S_IROTH;
+
+ if (uAttributes & osl_File_Attribute_OthWrite)
+ nNewMode|=S_IWOTH;
+
+ if (uAttributes & osl_File_Attribute_OthExe)
+ nNewMode|=S_IXOTH;
+
+ if (chmod(pszFilePath, nNewMode) < 0)
+ osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
+
+ return osl_error;
+}
+
+oslFileError SAL_CALL osl_setFileAttributes( rtl_uString* ustrFileURL, sal_uInt64 uAttributes )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrFileURL );
+
+ /* convert file url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return osl_psz_setFileAttributes( path, uAttributes );
+}
+
+/****************************************************************************/
+/* osl_setFileTime */
+/****************************************************************************/
+
+static oslFileError osl_psz_setFileTime (
+ const sal_Char* pszFilePath,
+ const TimeValue* /*pCreationTime*/,
+ const TimeValue* pLastAccessTime,
+ const TimeValue* pLastWriteTime )
+{
+ int nRet=0;
+ struct utimbuf aTimeBuffer;
+ struct stat aFileStat;
+#ifdef DEBUG_OSL_FILE
+ struct tm* pTM=0;
+#endif
+
+ nRet = lstat(pszFilePath,&aFileStat);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"File Times are (in localtime):\n");
+ pTM=localtime(&aFileStat.st_ctime);
+ fprintf(stderr,"CreationTime is '%s'\n",asctime(pTM));
+ pTM=localtime(&aFileStat.st_atime);
+ fprintf(stderr,"AccessTime is '%s'\n",asctime(pTM));
+ pTM=localtime(&aFileStat.st_mtime);
+ fprintf(stderr,"Modification is '%s'\n",asctime(pTM));
+
+ fprintf(stderr,"File Times are (in UTC):\n");
+ fprintf(stderr,"CreationTime is '%s'\n",ctime(&aFileStat.st_ctime));
+ fprintf(stderr,"AccessTime is '%s'\n",ctime(&aTimeBuffer.actime));
+ fprintf(stderr,"Modification is '%s'\n",ctime(&aTimeBuffer.modtime));
+#endif
+
+ if ( pLastAccessTime != 0 )
+ {
+ aTimeBuffer.actime=pLastAccessTime->Seconds;
+ }
+ else
+ {
+ aTimeBuffer.actime=aFileStat.st_atime;
+ }
+
+ if ( pLastWriteTime != 0 )
+ {
+ aTimeBuffer.modtime=pLastWriteTime->Seconds;
+ }
+ else
+ {
+ aTimeBuffer.modtime=aFileStat.st_mtime;
+ }
+
+ /* mfe: Creation time not used here! */
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"File Times are (in localtime):\n");
+ pTM=localtime(&aFileStat.st_ctime);
+ fprintf(stderr,"CreationTime now '%s'\n",asctime(pTM));
+ pTM=localtime(&aTimeBuffer.actime);
+ fprintf(stderr,"AccessTime now '%s'\n",asctime(pTM));
+ pTM=localtime(&aTimeBuffer.modtime);
+ fprintf(stderr,"Modification now '%s'\n",asctime(pTM));
+
+ fprintf(stderr,"File Times are (in UTC):\n");
+ fprintf(stderr,"CreationTime now '%s'\n",ctime(&aFileStat.st_ctime));
+ fprintf(stderr,"AccessTime now '%s'\n",ctime(&aTimeBuffer.actime));
+ fprintf(stderr,"Modification now '%s'\n",ctime(&aTimeBuffer.modtime));
+#endif
+
+ nRet=utime(pszFilePath,&aTimeBuffer);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+
+oslFileError SAL_CALL osl_setFileTime (
+ rtl_uString* ustrFileURL,
+ const TimeValue* pCreationTime,
+ const TimeValue* pLastAccessTime,
+ const TimeValue* pLastWriteTime )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrFileURL );
+
+ /* convert file url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
+}
diff --git a/sal/osl/unx/file_url.cxx b/sal/osl/unx/file_url.cxx
index 4a4d97a7a..3fe0679bc 100644
--- a/sal/osl/unx/file_url.cxx
+++ b/sal/osl/unx/file_url.cxx
@@ -30,45 +30,31 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"
+
+#include "file_url.h"
+
#include "system.h"
-#ifndef _LIMITS_H
#include <limits.h>
-#endif
-
-#ifndef _ERRNO_H
#include <errno.h>
-#endif
-
-#ifndef _STRINGS_H
#include <strings.h>
-#endif
-
-#ifndef _UNISTD_H
#include <unistd.h>
-#endif
-#include <osl/file.h>
+
+#include "osl/file.hxx"
#include <osl/security.h>
-#include <rtl/uri.h>
#include <osl/diagnose.h>
+#include <osl/thread.h>
+#include <osl/process.h>
+
+#include <rtl/uri.h>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.h>
+#include "rtl/textcvt.h"
-#ifndef _OSL_TREAD_H_
-#include <osl/thread.h>
-#endif
-#include <osl/file.hxx>
-#include <osl/process.h>
#include "file_error_transl.h"
-
-#ifndef _FILE_URL_H_
-#include "file_url.h"
-#endif
#include "file_path_helper.hxx"
-#ifndef _OSL_UUNXAPI_HXX_
#include "uunxapi.hxx"
-#endif
/***************************************************
@@ -84,16 +70,14 @@
so this code should be consolidated.
**************************************************/
+/************************************************************************
+ * ToDo
+ *
+ * Fix osl_getCanonicalName
+ *
+ ***********************************************************************/
-
-/***************************************************
- * forward
- **************************************************/
-
-extern "C" int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32);
-extern "C" int TextToUnicode(const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
-
/***************************************************
* namespace directives
**************************************************/
@@ -151,6 +135,18 @@ static sal_Bool findWrongUsage( const sal_Unicode *path, sal_Int32 len )
*/
/****************************************************************************/
+/* osl_getCanonicalName */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
+{
+ OSL_ENSURE(0, "osl_getCanonicalName not implemented");
+
+ rtl_uString_newFromString(pustrValidURL, ustrFileURL);
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
/* osl_getSystemPathFromFileURL */
/****************************************************************************/
@@ -850,3 +846,120 @@ oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileUR
return osl_error;
}
+
+/*****************************************************************************
+ * UnicodeToText
+ ****************************************************************************/
+
+namespace /* private */
+{
+ class UnicodeToTextConverter_Impl
+ {
+ rtl_UnicodeToTextConverter m_converter;
+
+ UnicodeToTextConverter_Impl()
+ : m_converter (rtl_createUnicodeToTextConverter (osl_getThreadTextEncoding()))
+ {}
+
+ ~UnicodeToTextConverter_Impl()
+ {
+ rtl_destroyUnicodeToTextConverter (m_converter);
+ }
+ public:
+ static UnicodeToTextConverter_Impl & getInstance()
+ {
+ static UnicodeToTextConverter_Impl g_theConverter;
+ return g_theConverter;
+ }
+
+ sal_Size convert(
+ sal_Unicode const * pSrcBuf, sal_Size nSrcChars, sal_Char * pDstBuf, sal_Size nDstBytes,
+ sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtChars)
+ {
+ OSL_ASSERT(m_converter != 0);
+ return rtl_convertUnicodeToText (
+ m_converter, 0, pSrcBuf, nSrcChars, pDstBuf, nDstBytes, nFlags, pInfo, pSrcCvtChars);
+ }
+ };
+} // end namespace private
+
+int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
+{
+ sal_uInt32 nInfo = 0;
+ sal_Size nSrcChars = 0;
+
+ sal_Size nDestBytes = UnicodeToTextConverter_Impl::getInstance().convert (
+ uniText, uniTextLen, buffer, bufLen,
+ OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH, &nInfo, &nSrcChars);
+
+ if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
+ {
+ errno = EOVERFLOW;
+ return 0;
+ }
+
+ /* ensure trailing '\0' */
+ buffer[nDestBytes] = '\0';
+ return nDestBytes;
+}
+
+/*****************************************************************************
+ * TextToUnicode
+ ****************************************************************************/
+
+namespace /* private */
+{
+ class TextToUnicodeConverter_Impl
+ {
+ rtl_TextToUnicodeConverter m_converter;
+
+ TextToUnicodeConverter_Impl()
+ : m_converter (rtl_createTextToUnicodeConverter (osl_getThreadTextEncoding()))
+ {}
+
+ ~TextToUnicodeConverter_Impl()
+ {
+ rtl_destroyTextToUnicodeConverter (m_converter);
+ }
+
+ public:
+ static TextToUnicodeConverter_Impl & getInstance()
+ {
+ static TextToUnicodeConverter_Impl g_theConverter;
+ return g_theConverter;
+ }
+
+ sal_Size convert(
+ sal_Char const * pSrcBuf, sal_Size nSrcBytes, sal_Unicode * pDstBuf, sal_Size nDstChars,
+ sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtBytes)
+ {
+ OSL_ASSERT(m_converter != 0);
+ return rtl_convertTextToUnicode (
+ m_converter, 0, pSrcBuf, nSrcBytes, pDstBuf, nDstChars, nFlags, pInfo, pSrcCvtBytes);
+ }
+ };
+} // end namespace private
+
+int TextToUnicode(
+ const char* text,
+ size_t text_buffer_size,
+ sal_Unicode* unic_text,
+ sal_Int32 unic_text_buffer_size)
+{
+ sal_uInt32 nInfo = 0;
+ sal_Size nSrcChars = 0;
+
+ sal_Size nDestBytes = TextToUnicodeConverter_Impl::getInstance().convert(
+ text, text_buffer_size, unic_text, unic_text_buffer_size,
+ OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH, &nInfo, &nSrcChars);
+
+ if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
+ {
+ errno = EOVERFLOW;
+ return 0;
+ }
+
+ /* ensure trailing '\0' */
+ unic_text[nDestBytes] = '\0';
+ return nDestBytes;
+}
diff --git a/sal/osl/unx/file_url.h b/sal/osl/unx/file_url.h
index 218ea3c68..50b070f5e 100644
--- a/sal/osl/unx/file_url.h
+++ b/sal/osl/unx/file_url.h
@@ -28,43 +28,45 @@
*
************************************************************************/
- /***************************************************
- * Internal header file, declares all functions
- * that are not part of the offical API and are
- * not defined in the osl header files
- **************************************************/
+#ifndef INCLUDED_FILE_URL_H
+#define INCLUDED_FILE_URL_H
- #ifndef _FILE_URL_H_
- #define _FILE_URL_H_
+#include "osl/file.h"
- #ifndef _FILE_H_
- #include <osl/file.h>
- #endif
+#ifdef __cplusplus
+extern "C"
+{
+#endif
- #ifdef __cplusplus
- extern "C"
- {
- #endif
+/**************************************************
+ * osl_getSystemPathFromFileURL_Ex
+ *************************************************/
- /**************************************************
- * _osl_getSystemPathFromFileURL
- *************************************************/
-
- #define FURL_ALLOW_RELATIVE sal_True
- #define FURL_DENY_RELATIVE sal_False
+#define FURL_ALLOW_RELATIVE sal_True
+#define FURL_DENY_RELATIVE sal_False
- oslFileError osl_getSystemPathFromFileURL_Ex(rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath, sal_Bool bAllowRelative);
+oslFileError osl_getSystemPathFromFileURL_Ex(rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath, sal_Bool bAllowRelative);
- /**************************************************
- * FileURLToPath
- *************************************************/
+/**************************************************
+ * FileURLToPath
+ *************************************************/
- oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileURL);
+oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileURL);
+/***************************************************
+ * UnicodeToText
+ **************************************************/
- #ifdef __cplusplus
- }
- #endif
+int UnicodeToText(char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen);
+
+/***************************************************
+ * TextToUniCode
+ **************************************************/
+int TextToUnicode(const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
+
+#ifdef __cplusplus
+}
+#endif
- #endif /* #define _FILE_URL_H_ */
+#endif /* #define INCLUDED_FILE_URL_H */
diff --git a/sal/osl/unx/file_volume.cxx b/sal/osl/unx/file_volume.cxx
new file mode 100644
index 000000000..66a0cef5e
--- /dev/null
+++ b/sal/osl/unx/file_volume.cxx
@@ -0,0 +1,1570 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "osl/file.h"
+
+#include "osl/diagnose.h"
+#include "osl/thread.h"
+#include "rtl/alloc.h"
+
+#include "file_error_transl.h"
+#include "file_url.h"
+#include "system.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#ifdef HAVE_STATFS_H
+#undef HAVE_STATFS_H
+#endif
+
+#if defined(SOLARIS)
+
+#include <sys/mnttab.h>
+#include <sys/statvfs.h>
+#define HAVE_STATFS_H
+#include <sys/fs/ufs_quota.h>
+static const sal_Char* MOUNTTAB="/etc/mnttab";
+
+#elif defined(LINUX)
+
+#include <mntent.h>
+#include <sys/vfs.h>
+#define HAVE_STATFS_H
+#include <sys/quota.h>
+//#include <ctype.h>
+static const sal_Char* MOUNTTAB="/etc/mtab";
+
+#elif defined(NETBSD) || defined(FREEBSD)
+
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <ufs/ufs/quota.h>
+//#include <ctype.h>
+#define HAVE_STATFS_H
+
+/* No mounting table on *BSD
+ * This information is stored only in the kernel. */
+/* static const sal_Char* MOUNTTAB="/etc/mtab"; */
+
+#elif defined(IRIX)
+
+#include <mntent.h>
+#include <sys/mount.h>
+#include <sys/statvfs.h>
+#define HAVE_STATFS_H
+#include <sys/quota.h>
+//#include <ctype.h>
+static const sal_Char* MOUNTTAB="/etc/mtab";
+
+#elif defined(MACOSX)
+
+#include <ufs/ufs/quota.h>
+//#include <ctype.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#define HAVE_STATFS_H
+// static const sal_Char* MOUNTTAB="/etc/mtab";
+
+#endif /* HAVE_STATFS_H */
+
+/************************************************************************
+ * ToDo
+ *
+ * - Fix: check for corresponding struct sizes in exported functions
+ * - check size/use of oslVolumeDeviceHandle
+ * - check size/use of oslVolumeInfo
+ ***********************************************************************/
+/******************************************************************************
+ *
+ * Data Type Definition
+ *
+ ******************************************************************************/
+
+typedef struct _oslVolumeDeviceHandleImpl
+{
+ sal_Char pszMountPoint[PATH_MAX];
+ sal_Char pszFilePath[PATH_MAX];
+ sal_Char pszDevice[PATH_MAX];
+ sal_Char ident[4];
+ sal_uInt32 RefCount;
+} oslVolumeDeviceHandleImpl;
+
+/******************************************************************************
+ *
+ * 'removeable device' aka floppy functions
+ *
+ *****************************************************************************/
+
+static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath);
+static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy);
+static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy);
+
+#if defined(SOLARIS)
+static sal_Bool osl_isFloppyMounted(sal_Char* pszPath, sal_Char* pszMountPath);
+static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, sal_Char* pBuffer);
+static sal_Bool osl_checkFloppyPath(sal_Char* pszPath, sal_Char* pszFilePath, sal_Char* pszDevicePath);
+#endif /* SOLARIS */
+
+#if defined(LINUX)
+static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice);
+static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem);
+#endif /* LINUX */
+
+
+#if defined(IRIX)
+static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice);
+static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem);
+#endif /* IRIX */
+
+#ifdef DEBUG_OSL_FILE
+static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
+#endif /* DEBUG_OSL_FILE */
+
+/******************************************************************************
+ *
+ * C-String Function Declarations
+ *
+ *****************************************************************************/
+
+static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
+
+/****************************************************************************/
+/* osl_getVolumeInformation */
+/****************************************************************************/
+
+oslFileError osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrDirectoryURL );
+ OSL_ASSERT( pInfo );
+
+ /* convert directory url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+#ifdef MACOSX
+ if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
+ return oslTranslateFileError( OSL_FET_ERROR, errno );
+#endif/* MACOSX */
+
+ return osl_psz_getVolumeInformation( path, pInfo, uFieldMask);
+}
+
+/******************************************************************************
+ *
+ * C-String Versions of Exported Module Functions
+ *
+ *****************************************************************************/
+
+#ifdef HAVE_STATFS_H
+
+#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
+# define __OSL_STATFS_STRUCT struct statfs
+# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
+# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
+# define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
+# define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
+
+/* always return true if queried for the properties of
+ the file system. If you think this is wrong under any
+ of the target platforms fix it!!!! */
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
+#endif /* FREEBSD || NETBSD || MACOSX */
+
+#if defined(LINUX)
+# define __OSL_NFS_SUPER_MAGIC 0x6969
+# define __OSL_SMB_SUPER_MAGIC 0x517B
+# define __OSL_MSDOS_SUPER_MAGIC 0x4d44
+# define __OSL_NTFS_SUPER_MAGIC 0x5346544e
+# define __OSL_STATFS_STRUCT struct statfs
+# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
+# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
+# define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
+# define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
+# define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
+#endif /* LINUX */
+
+#if defined(SOLARIS) || defined(IRIX)
+# define __OSL_STATFS_STRUCT struct statvfs
+# define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
+# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
+# define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
+# define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
+
+/* always return true if queried for the properties of
+ the file system. If you think this is wrong under any
+ of the target platforms fix it!!!! */
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
+#endif /* SOLARIS || IRIX*/
+
+# define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
+
+#else /* no statfs available */
+
+# define __OSL_STATFS_STRUCT struct dummy {int i;}
+# define __OSL_STATFS_INIT(a) ((void)0)
+# define __OSL_STATFS(dir, sfs) (1)
+# define __OSL_STATFS_ISREMOTE(sfs) (0)
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
+#endif /* HAVE_STATFS_H */
+
+
+static oslFileError osl_psz_getVolumeInformation (
+ const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
+{
+ __OSL_STATFS_STRUCT sfs;
+
+ if (!pInfo)
+ return osl_File_E_INVAL;
+
+ __OSL_STATFS_INIT(sfs);
+
+ pInfo->uValidFields = 0;
+ pInfo->uAttributes = 0;
+
+ if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
+ {
+ oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
+ return (result);
+ }
+
+ /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
+ if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
+ {
+ if (__OSL_STATFS_ISREMOTE(sfs))
+ pInfo->uAttributes |= osl_Volume_Attribute_Remote;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+
+ if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
+ {
+ if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
+ pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
+
+ if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
+ pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+
+ pInfo->uTotalSpace = 0;
+ pInfo->uFreeSpace = 0;
+ pInfo->uUsedSpace = 0;
+
+#if defined(__OSL_STATFS_BLKSIZ)
+
+ if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
+ (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
+ {
+ pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
+ pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
+ }
+
+ if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
+ (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
+ {
+ pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
+
+ if (getuid() == 0)
+ pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
+ else
+ pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
+ }
+
+#endif /* __OSL_STATFS_BLKSIZ */
+
+ if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
+ (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
+ {
+ pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
+ }
+
+ pInfo->uMaxNameLength = 0;
+ if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
+ {
+ long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
+ if (nLen > 0)
+ {
+ pInfo->uMaxNameLength = (sal_uInt32)nLen;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
+ }
+ }
+
+ pInfo->uMaxPathLength = 0;
+ if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
+ {
+ long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
+ if (nLen > 0)
+ {
+ pInfo->uMaxPathLength = (sal_uInt32)nLen;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
+ }
+ }
+
+#if defined(__OSL_STATFS_TYPENAME)
+
+ if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
+ {
+ rtl_string2UString(
+ &(pInfo->ustrFileSystemName),
+ __OSL_STATFS_TYPENAME(sfs),
+ rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
+ osl_getThreadTextEncoding(),
+ OUSTRING_TO_OSTRING_CVTFLAGS);
+ OSL_ASSERT(pInfo->ustrFileSystemName != 0);
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
+ }
+
+#endif /* __OSL_STATFS_TYPENAME */
+
+ if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
+ {
+ /* FIXME: check also entries in mntent for the device
+ and fill it with correct values */
+
+ *pInfo->pDeviceHandle = osl_isFloppyDrive(pszDirectory);
+
+ if (*pInfo->pDeviceHandle)
+ {
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
+ pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+ }
+ return osl_File_E_None;
+}
+
+/******************************************************************************
+ *
+ * GENERIC FLOPPY FUNCTIONS
+ *
+ *****************************************************************************/
+
+
+/*****************************************
+ * osl_unmountVolumeDevice
+ ****************************************/
+
+oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
+{
+ oslFileError tErr = osl_File_E_NOSYS;
+
+ tErr = osl_unmountFloppy(Handle);
+
+ /* Perhaps current working directory is set to mount point */
+
+ if ( tErr )
+ {
+ sal_Char *pszHomeDir = getenv("HOME");
+
+ if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
+ {
+ /* try again */
+
+ tErr = osl_unmountFloppy(Handle);
+
+ OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
+ }
+ }
+
+ return tErr;
+}
+
+/*****************************************
+ * osl_automountVolumeDevice
+ ****************************************/
+
+oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
+{
+ oslFileError tErr = osl_File_E_NOSYS;
+
+ tErr = osl_mountFloppy(Handle);
+
+ return tErr;
+}
+
+/*****************************************
+ * osl_getVolumeDeviceMountPath
+ ****************************************/
+static rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
+{
+ rtl_string2UString(
+ ustrValid,
+ pszStr,
+ rtl_str_getLength( pszStr ),
+ osl_getThreadTextEncoding(),
+ OUSTRING_TO_OSTRING_CVTFLAGS );
+ OSL_ASSERT(*ustrValid != 0);
+
+ return *ustrValid;
+}
+
+oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
+{
+ oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
+ sal_Char Buffer[PATH_MAX];
+
+ Buffer[0] = '\0';
+
+ if ( pItem == 0 || pstrPath == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+ return osl_File_E_INVAL;
+ }
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"Handle is:\n");
+ osl_printFloppyHandle(pItem);
+#endif
+
+ snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
+#endif
+
+ oslMakeUStrFromPsz(Buffer, pstrPath);
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_acquireVolumeDeviceHandle
+ ****************************************/
+
+oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
+{
+ oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
+
+ if ( pItem == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ ++pItem->RefCount;
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_releaseVolumeDeviceHandle
+ ****************************************/
+
+oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
+{
+ oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
+
+ if ( pItem == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ --pItem->RefCount;
+
+ if ( pItem->RefCount == 0 )
+ {
+ rtl_freeMemory(pItem);
+ }
+
+ return osl_File_E_None;
+}
+
+#ifndef MACOSX
+
+/*****************************************
+ * osl_newVolumeDeviceHandleImpl
+ ****************************************/
+
+static oslVolumeDeviceHandleImpl* osl_newVolumeDeviceHandleImpl()
+{
+ oslVolumeDeviceHandleImpl* pHandle;
+ const size_t nSizeOfHandle = sizeof(oslVolumeDeviceHandleImpl);
+
+ pHandle = (oslVolumeDeviceHandleImpl*) rtl_allocateMemory (nSizeOfHandle);
+ if (pHandle != NULL)
+ {
+ pHandle->ident[0] = 'O';
+ pHandle->ident[1] = 'V';
+ pHandle->ident[2] = 'D';
+ pHandle->ident[3] = 'H';
+ pHandle->pszMountPoint[0] = '\0';
+ pHandle->pszFilePath[0] = '\0';
+ pHandle->pszDevice[0] = '\0';
+ pHandle->RefCount = 1;
+ }
+ return pHandle;
+}
+
+/*****************************************
+ * osl_freeVolumeDeviceHandleImpl
+ ****************************************/
+
+static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
+{
+ if (pHandle != NULL)
+ rtl_freeMemory (pHandle);
+}
+#endif
+
+/******************************************************************************
+ *
+ * SOLARIS FLOPPY FUNCTIONS
+ *
+ *****************************************************************************/
+
+#if defined(SOLARIS)
+/* compare a given devicename with the typical device names on a Solaris box */
+static sal_Bool
+osl_isAFloppyDevice (const char* pDeviceName)
+{
+ const char* pFloppyDevice [] = {
+ "/dev/fd", "/dev/rfd",
+ "/dev/diskette", "/dev/rdiskette",
+ "/vol/dev/diskette", "/vol/dev/rdiskette"
+ };
+
+ int i;
+ for (i = 0; i < (sizeof(pFloppyDevice)/sizeof(pFloppyDevice[0])); i++)
+ {
+ if (strncmp(pDeviceName, pFloppyDevice[i], strlen(pFloppyDevice[i])) == 0)
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/* compare two directories whether the first may be a parent of the second. this
+ * does not realpath() resolving */
+static sal_Bool
+osl_isAParentDirectory (const char* pParentDir, const char* pSubDir)
+{
+ return strncmp(pParentDir, pSubDir, strlen(pParentDir)) == 0;
+}
+
+/* the name of the routine is obviously silly. But anyway create a
+ * oslVolumeDeviceHandle with correct mount point, device name and a resolved filepath
+ * only if pszPath points to file or directory on a floppy */
+static oslVolumeDeviceHandle
+osl_isFloppyDrive(const sal_Char* pszPath)
+{
+ FILE* pMountTab;
+ struct mnttab aMountEnt;
+ oslVolumeDeviceHandleImpl* pHandle;
+
+ if ((pHandle = osl_newVolumeDeviceHandleImpl()) == NULL)
+ {
+ return NULL;
+ }
+ if (realpath(pszPath, pHandle->pszFilePath) == NULL)
+ {
+ osl_freeVolumeDeviceHandleImpl (pHandle);
+ return NULL;
+ }
+ if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
+ {
+ osl_freeVolumeDeviceHandleImpl (pHandle);
+ return NULL;
+ }
+
+ while (getmntent(pMountTab, &aMountEnt) == 0)
+ {
+ const char *pMountPoint = aMountEnt.mnt_mountp;
+ const char *pDevice = aMountEnt.mnt_special;
+ if ( osl_isAParentDirectory (aMountEnt.mnt_mountp, pHandle->pszFilePath)
+ && osl_isAFloppyDevice (aMountEnt.mnt_special))
+ {
+ /* skip the last item for it is the name of the disk */
+ char * pc = strrchr( aMountEnt.mnt_special, '/' );
+
+ if ( NULL != pc )
+ {
+ int len = pc - aMountEnt.mnt_special;
+
+ strncpy( pHandle->pszDevice, aMountEnt.mnt_special, len );
+ pHandle->pszDevice[len] = '\0';
+ }
+ else
+ {
+ /* #106048 use save str functions to avoid buffer overflows */
+ memset(pHandle->pszDevice, 0, sizeof(pHandle->pszDevice));
+ strncpy(pHandle->pszDevice, aMountEnt.mnt_special, sizeof(pHandle->pszDevice) - 1);
+ }
+
+ /* remember the mount point */
+ memset(pHandle->pszMountPoint, 0, sizeof(pHandle->pszMountPoint));
+ strncpy(pHandle->pszMountPoint, aMountEnt.mnt_mountp, sizeof(pHandle->pszMountPoint) - 1);
+
+ fclose (pMountTab);
+ return pHandle;
+ }
+ }
+
+ fclose (pMountTab);
+ osl_freeVolumeDeviceHandleImpl (pHandle);
+ return NULL;
+}
+
+static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ FILE* pMountTab;
+ struct mnttab aMountEnt;
+ oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
+
+ int nRet=0;
+ sal_Char pszCmd[512] = "";
+
+ if ( pHandle == 0 )
+ return osl_File_E_INVAL;
+
+ /* FIXME: don't know what this is good for */
+ if ( pHandle->ident[0] != 'O' || pHandle->ident[1] != 'V' || pHandle->ident[2] != 'D' || pHandle->ident[3] != 'H' )
+ return osl_File_E_INVAL;
+
+ snprintf(pszCmd, sizeof(pszCmd), "eject -q %s > /dev/null 2>&1", pHandle->pszDevice);
+
+ nRet = system( pszCmd );
+
+ switch ( WEXITSTATUS(nRet) )
+ {
+ case 0:
+ {
+ /* lookup the device in mount tab again */
+ if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
+ return osl_File_E_BUSY;
+
+ while (getmntent(pMountTab, &aMountEnt) == 0)
+ {
+ const char *pMountPoint = aMountEnt.mnt_mountp;
+ const char *pDevice = aMountEnt.mnt_special;
+ if ( 0 == strncmp( pHandle->pszDevice, aMountEnt.mnt_special, strlen(pHandle->pszDevice) ) )
+ {
+ memset(pHandle->pszMountPoint, 0, sizeof(pHandle->pszMountPoint));
+ strncpy (pHandle->pszMountPoint, aMountEnt.mnt_mountp, sizeof(pHandle->pszMountPoint) - 1);
+
+ fclose (pMountTab);
+ return osl_File_E_None;
+ }
+ }
+
+ fclose (pMountTab);
+ return osl_File_E_BUSY;
+ }
+ //break; // break not necessary here, see return statements before
+
+ case 1:
+ return osl_File_E_BUSY;
+
+ default:
+ break;
+ }
+
+ return osl_File_E_BUSY;
+}
+
+static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+// FILE* pMountTab;
+// struct mnttab aMountEnt;
+ oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
+
+ int nRet=0;
+ sal_Char pszCmd[512] = "";
+
+ if ( pHandle == 0 )
+ return osl_File_E_INVAL;
+
+ /* FIXME: don't know what this is good for */
+ if ( pHandle->ident[0] != 'O' || pHandle->ident[1] != 'V' || pHandle->ident[2] != 'D' || pHandle->ident[3] != 'H' )
+ return osl_File_E_INVAL;
+
+ snprintf(pszCmd, sizeof(pszCmd), "eject %s > /dev/null 2>&1", pHandle->pszDevice);
+
+ nRet = system( pszCmd );
+
+ switch ( WEXITSTATUS(nRet) )
+ {
+ case 0:
+ {
+ FILE* pMountTab;
+ struct mnttab aMountEnt;
+
+ /* lookup if device is still in mount tab */
+ if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
+ return osl_File_E_BUSY;
+
+ while (getmntent(pMountTab, &aMountEnt) == 0)
+ {
+ const char *pMountPoint = aMountEnt.mnt_mountp;
+ const char *pDevice = aMountEnt.mnt_special;
+ if ( 0 == strncmp( pHandle->pszDevice, aMountEnt.mnt_special, strlen(pHandle->pszDevice) ) )
+ {
+ fclose (pMountTab);
+ return osl_File_E_BUSY;
+ }
+ }
+
+ fclose (pMountTab);
+ pHandle->pszMountPoint[0] = 0;
+ return osl_File_E_None;
+ }
+
+ //break; //break not necessary, see return statements before
+
+ case 1:
+ return osl_File_E_NODEV;
+
+ case 4:
+ pHandle->pszMountPoint[0] = 0;
+ return osl_File_E_None;
+
+ default:
+ break;
+ }
+
+ return osl_File_E_BUSY;
+}
+
+#endif /* SOLARIS */
+
+/******************************************************************************
+ *
+ * LINUX FLOPPY FUNCTIONS
+ *
+ *****************************************************************************/
+
+#if defined(LINUX)
+static oslVolumeDeviceHandle
+osl_isFloppyDrive (const sal_Char* pszPath)
+{
+ oslVolumeDeviceHandleImpl* pItem = osl_newVolumeDeviceHandleImpl();
+ if (osl_getFloppyMountEntry(pszPath, pItem))
+ return (oslVolumeDeviceHandle) pItem;
+
+ osl_freeVolumeDeviceHandleImpl (pItem);
+ return 0;
+}
+#endif /* LINUX */
+
+#if defined(LINUX)
+static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ sal_Bool bRet = sal_False;
+ oslVolumeDeviceHandleImpl* pItem=0;
+ int nRet;
+ sal_Char pszCmd[PATH_MAX];
+ const sal_Char* pszMountProg = "mount";
+ sal_Char* pszSuDo = 0;
+ sal_Char* pszTmp = 0;
+
+ pszCmd[0] = '\0';
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"In osl_mountFloppy\n");
+#endif
+
+ pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
+
+ if ( pItem == 0 )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_mountFloppy [pItem == 0]\n");
+#endif
+
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_mountFloppy [invalid handle]\n");
+#endif
+ return osl_File_E_INVAL;
+ }
+
+ bRet = osl_isFloppyMounted(pItem);
+ if ( bRet == sal_True )
+ {
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"detected mounted floppy at '%s'\n",pItem->pszMountPoint);
+#endif
+ return osl_File_E_BUSY;
+ }
+
+ /* mfe: we can't use the mount(2) system call!!! */
+ /* even if we are root */
+ /* since mtab is not updated!!! */
+ /* but we need it to be updated */
+ /* some "magic" must be done */
+
+/* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
+/* if ( nRet != 0 ) */
+/* { */
+/* nRet=errno; */
+/* #ifdef DEBUG_OSL_FILE */
+/* perror("mount"); */
+/* #endif */
+/* } */
+
+ pszTmp = getenv("SAL_MOUNT_MOUNTPROG");
+ if ( pszTmp != 0 )
+ {
+ pszMountProg=pszTmp;
+ }
+
+ pszTmp=getenv("SAL_MOUNT_SU_DO");
+ if ( pszTmp != 0 )
+ {
+ pszSuDo=pszTmp;
+ }
+
+ if ( pszSuDo != 0 )
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s %s %s",pszSuDo,pszMountProg,pItem->pszDevice,pItem->pszMountPoint);
+ }
+ else
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszMountProg,pItem->pszMountPoint);
+ }
+
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"executing '%s'\n",pszCmd);
+#endif
+
+ nRet = system(pszCmd);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"call returned '%i'\n",nRet);
+ fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
+#endif
+
+
+ switch ( WEXITSTATUS(nRet) )
+ {
+ case 0:
+ nRet=0;
+ break;
+
+ case 2:
+ nRet=EPERM;
+ break;
+
+ case 4:
+ nRet=ENOENT;
+ break;
+
+ case 8:
+ nRet=EINTR;
+ break;
+
+ case 16:
+ nRet=EPERM;
+ break;
+
+ case 32:
+ nRet=EBUSY;
+ break;
+
+ case 64:
+ nRet=EAGAIN;
+ break;
+
+ default:
+ nRet=EBUSY;
+ break;
+ }
+
+ return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
+}
+#endif /* LINUX */
+
+
+#if defined(LINUX)
+static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ oslVolumeDeviceHandleImpl* pItem=0;
+ int nRet=0;
+ sal_Char pszCmd[PATH_MAX];
+ sal_Char* pszTmp = 0;
+ sal_Char* pszSuDo = 0;
+ const sal_Char* pszUmountProg = "umount";
+
+ pszCmd[0] = '\0';
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"In osl_unmountFloppy\n");
+#endif
+
+ pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
+
+ if ( pItem == 0 )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_unmountFloppy [pItem==0]\n");
+#endif
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_unmountFloppy [invalid handle]\n");
+#endif
+ return osl_File_E_INVAL;
+ }
+
+ /* mfe: we can't use the umount(2) system call!!! */
+ /* even if we are root */
+ /* since mtab is not updated!!! */
+ /* but we need it to be updated */
+ /* some "magic" must be done */
+
+/* nRet=umount(pItem->pszDevice); */
+/* if ( nRet != 0 ) */
+/* { */
+/* nRet = errno; */
+
+/* #ifdef DEBUG_OSL_FILE */
+/* perror("mount"); */
+/* #endif */
+/* } */
+
+
+ pszTmp = getenv("SAL_MOUNT_UMOUNTPROG");
+ if ( pszTmp != 0 )
+ {
+ pszUmountProg=pszTmp;
+ }
+
+ pszTmp = getenv("SAL_MOUNT_SU_DO");
+ if ( pszTmp != 0 )
+ {
+ pszSuDo=pszTmp;
+ }
+
+ if ( pszSuDo != 0 )
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s %s",pszSuDo,pszUmountProg,pItem->pszMountPoint);
+ }
+ else
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszUmountProg,pItem->pszMountPoint);
+ }
+
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"executing '%s'\n",pszCmd);
+#endif
+
+ nRet = system(pszCmd);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"call returned '%i'\n",nRet);
+ fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
+#endif
+
+ switch ( WEXITSTATUS(nRet) )
+ {
+ case 0:
+ nRet=0;
+ break;
+
+ default:
+ nRet=EBUSY;
+ break;
+ }
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_unmountFloppy [ok]\n");
+#endif
+
+ return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
+
+/* return osl_File_E_None;*/
+}
+
+#endif /* LINUX */
+
+#if defined(LINUX)
+static sal_Bool
+osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
+{
+ struct mntent* pMountEnt;
+ FILE* pMountTab;
+
+ pMountTab = setmntent (MOUNTTAB, "r");
+ if (pMountTab == 0)
+ return sal_False;
+
+ while ((pMountEnt = getmntent(pMountTab)) != 0)
+ {
+ if ( strncmp(pMountEnt->mnt_dir, pszPath, strlen(pMountEnt->mnt_dir)) == 0
+ && strncmp(pMountEnt->mnt_fsname, "/dev/fd", strlen("/dev/fd")) == 0)
+ {
+ memset(pItem->pszMountPoint, 0, sizeof(pItem->pszMountPoint));
+ strncpy(pItem->pszMountPoint, pMountEnt->mnt_dir, sizeof(pItem->pszMountPoint) - 1);
+
+ memset(pItem->pszFilePath, 0, sizeof(pItem->pszFilePath));
+ strncpy(pItem->pszFilePath, pMountEnt->mnt_dir, sizeof(pItem->pszFilePath) - 1);
+
+ memset(pItem->pszDevice, 0, sizeof(pItem->pszDevice));
+ strncpy(pItem->pszDevice, pMountEnt->mnt_fsname, sizeof(pItem->pszDevice) - 1);
+
+ endmntent (pMountTab);
+ return sal_True;
+ }
+ }
+
+ endmntent (pMountTab);
+ return sal_False;
+}
+#endif /* LINUX */
+
+#if defined(LINUX)
+static sal_Bool
+osl_isFloppyMounted (oslVolumeDeviceHandleImpl* pDevice)
+{
+ oslVolumeDeviceHandleImpl aItem;
+
+ if ( osl_getFloppyMountEntry (pDevice->pszMountPoint, &aItem)
+ && strcmp (aItem.pszMountPoint, pDevice->pszMountPoint) == 0
+ && strcmp (aItem.pszDevice, pDevice->pszDevice) == 0)
+ {
+ return sal_True;
+ }
+ return sal_False;
+}
+#endif /* LINUX */
+
+/******************************************************************************
+ *
+ * IRIX FLOPPY FUNCTIONS
+ *
+ *****************************************************************************/
+
+#if defined(IRIX)
+static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
+{
+ oslVolumeDeviceHandleImpl* pItem = osl_newVolumeDeviceHandleImpl ();
+ sal_Bool bRet = sal_False;
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"In osl_isFloppyDrive\n");
+#endif
+
+ bRet=osl_getFloppyMountEntry(pszPath,pItem);
+
+ if ( bRet == sal_False )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_isFloppyDrive [not a floppy]\n");
+#endif
+ rtl_freeMemory(pItem);
+ return 0;
+ }
+
+
+#ifdef DEBUG_OSL_FILE
+ osl_printFloppyHandle(pItem);
+#endif
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_isFloppyDrive [ok]\n");
+#endif
+
+ return (oslVolumeDeviceHandle) pItem;
+}
+
+
+static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ sal_Bool bRet = sal_False;
+ oslVolumeDeviceHandleImpl* pItem=0;
+ int nRet;
+ sal_Char pszCmd[PATH_MAX];
+ sal_Char* pszMountProg = "mount";
+ sal_Char* pszSuDo = 0;
+ sal_Char* pszTmp = 0;
+
+ pszCmd[0] = '\0';
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"In osl_mountFloppy\n");
+#endif
+
+ pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
+
+ if ( pItem == 0 )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_mountFloppy [pItem == 0]\n");
+#endif
+
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_mountFloppy [invalid handle]\n");
+#endif
+ return osl_File_E_INVAL;
+ }
+
+ bRet = osl_isFloppyMounted(pItem);
+ if ( bRet == sal_True )
+ {
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"detected mounted floppy at '%s'\n",pItem->pszMountPoint);
+#endif
+ return osl_File_E_BUSY;
+ }
+
+ /* mfe: we can't use the mount(2) system call!!! */
+ /* even if we are root */
+ /* since mtab is not updated!!! */
+ /* but we need it to be updated */
+ /* some "magic" must be done */
+
+/* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
+/* if ( nRet != 0 ) */
+/* { */
+/* nRet=errno; */
+/* #ifdef DEBUG_OSL_FILE */
+/* perror("mount"); */
+/* #endif */
+/* } */
+
+ pszTmp = getenv("SAL_MOUNT_MOUNTPROG");
+ if ( pszTmp != 0 )
+ {
+ pszMountProg=pszTmp;
+ }
+
+ pszTmp=getenv("SAL_MOUNT_SU_DO");
+ if ( pszTmp != 0 )
+ {
+ pszSuDo=pszTmp;
+ }
+
+ if ( pszSuDo != 0 )
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s %s %s",pszSuDo,pszMountProg,pItem->pszDevice,pItem->pszMountPoint);
+ }
+ else
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszMountProg,pItem->pszMountPoint);
+ }
+
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"executing '%s'\n",pszCmd);
+#endif
+
+ nRet = system(pszCmd);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"call returned '%i'\n",nRet);
+ fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
+#endif
+
+
+ switch ( WEXITSTATUS(nRet) )
+ {
+ case 0:
+ nRet=0;
+ break;
+
+ case 2:
+ nRet=EPERM;
+ break;
+
+ case 4:
+ nRet=ENOENT;
+ break;
+
+ case 8:
+ nRet=EINTR;
+ break;
+
+ case 16:
+ nRet=EPERM;
+ break;
+
+ case 32:
+ nRet=EBUSY;
+ break;
+
+ case 64:
+ nRet=EAGAIN;
+ break;
+
+ default:
+ nRet=EBUSY;
+ break;
+ }
+
+ return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
+}
+
+static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ oslVolumeDeviceHandleImpl* pItem=0;
+ int nRet=0;
+ sal_Char pszCmd[PATH_MAX];
+ sal_Char* pszTmp = 0;
+ sal_Char* pszSuDo = 0;
+ sal_Char* pszUmountProg = "umount";
+
+ pszCmd[0] = '\0';
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"In osl_unmountFloppy\n");
+#endif
+
+ pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
+
+ if ( pItem == 0 )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_unmountFloppy [pItem==0]\n");
+#endif
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_unmountFloppy [invalid handle]\n");
+#endif
+ return osl_File_E_INVAL;
+ }
+
+ /* mfe: we can't use the umount(2) system call!!! */
+ /* even if we are root */
+ /* since mtab is not updated!!! */
+ /* but we need it to be updated */
+ /* some "magic" must be done */
+
+/* nRet=umount(pItem->pszDevice); */
+/* if ( nRet != 0 ) */
+/* { */
+/* nRet = errno; */
+
+/* #ifdef DEBUG_OSL_FILE */
+/* perror("mount"); */
+/* #endif */
+/* } */
+
+
+ pszTmp = getenv("SAL_MOUNT_UMOUNTPROG");
+ if ( pszTmp != 0 )
+ {
+ pszUmountProg=pszTmp;
+ }
+
+ pszTmp = getenv("SAL_MOUNT_SU_DO");
+ if ( pszTmp != 0 )
+ {
+ pszSuDo=pszTmp;
+ }
+
+ if ( pszSuDo != 0 )
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s %s",pszSuDo,pszUmountProg,pItem->pszMountPoint);
+ }
+ else
+ {
+ snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszUmountProg,pItem->pszMountPoint);
+ }
+
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"executing '%s'\n",pszCmd);
+#endif
+
+ nRet = system(pszCmd);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"call returned '%i'\n",nRet);
+ fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
+#endif
+
+ switch ( WEXITSTATUS(nRet) )
+ {
+ case 0:
+ nRet=0;
+ break;
+
+ default:
+ nRet=EBUSY;
+ break;
+ }
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_unmountFloppy [ok]\n");
+#endif
+
+ return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
+
+/* return osl_File_E_None;*/
+}
+
+static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
+{
+ struct mntent* pMountEnt=0;
+ sal_Char buffer[PATH_MAX];
+ FILE* mntfile=0;
+ int nRet=0;
+
+ buffer[0] = '\0';
+
+ mntfile = setmntent(MOUNTTAB,"r");
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"In osl_getFloppyMountEntry\n");
+#endif
+
+ memset(buffer, 0, sizeof(buffer));
+ strncpy(buffer, pszPath, sizeof(buffer) - 1);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"Checking mount of %s\n",buffer);
+#endif
+
+
+ if ( mntfile == 0 )
+ {
+ nRet=errno;
+#ifdef DEBUG_OSL_FILE
+ perror("mounttab");
+#endif
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_getFloppyMountEntry [mntfile]\n");
+#endif
+ return sal_False;
+ }
+
+ pMountEnt=getmntent(mntfile);
+ while ( pMountEnt != 0 )
+ {
+#ifdef DEBUG_OSL_FILE
+/* fprintf(stderr,"mnt_fsname : %s\n",pMountEnt->mnt_fsname); */
+/* fprintf(stderr,"mnt_dir : %s\n",pMountEnt->mnt_dir); */
+/* fprintf(stderr,"mnt_type : %s\n",pMountEnt->mnt_type);*/
+#endif
+ if ( strcmp(pMountEnt->mnt_dir,buffer) == 0 &&
+ strncmp(pMountEnt->mnt_fsname,"/dev/fd",strlen("/dev/fd")) == 0 )
+ {
+
+ memset(pItem->pszMountPoint, 0, sizeof(pItem->pszMountPoint));
+ strncpy(pItem->pszMountPoint, pMountEnt->mnt_dir, sizeof(pItem->pszMountPoint) - 1);
+
+ memset(pItem->pszFilePath, 0, sizeof(pItem->pszFilePath));
+ strncpy(pItem->pszFilePath, pMountEnt->mnt_dir, sizeof(pItem->pszFilePath) - 1);
+
+ memset(pItem->pszDevice, 0, sizeof(pItem->pszDevice));
+ strncpy(pItem->pszDevice, pMountEnt->mnt_fsname, sizeof(pItem->pszDevice) - 1);
+
+ fclose(mntfile);
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"Mount Point found '%s'\n",pItem->pszMountPoint);
+#endif
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_getFloppyMountEntry [found]\n");
+#endif
+ return sal_True;
+ }
+#ifdef DEBUG_OSL_FILE
+/* fprintf(stderr,"=================\n");*/
+#endif
+ pMountEnt=getmntent(mntfile);
+ }
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_getFloppyMountEntry [not found]\n");
+#endif
+
+ fclose(mntfile);
+ return sal_False;
+}
+
+static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
+{
+ sal_Char buffer[PATH_MAX];
+ oslVolumeDeviceHandleImpl* pItem=0;
+ sal_Bool bRet=0;
+
+ buffer[0] = '\0';
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"In osl_isFloppyMounted\n");
+#endif
+
+ pItem = osl_newVolumeDeviceHandleImpl ();
+ if ( pItem == 0 )
+ return osl_File_E_NOMEM;
+
+ memset(buffer, 0, sizeof(buffer));
+ strncpy(buffer, pDevice->pszMountPoint, sizeof(buffer) - 1);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"Checking mount of %s\n",buffer);
+#endif
+
+ bRet = osl_getFloppyMountEntry(buffer,pItem);
+
+ if ( bRet == sal_False )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_isFloppyMounted [not mounted]\n");
+#endif
+ return sal_False;
+ }
+
+ if (strcmp(pItem->pszMountPoint, pDevice->pszMountPoint) == 0 &&
+ strcmp(pItem->pszDevice,pDevice->pszDevice) == 0)
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_isFloppyMounted [is mounted]\n");
+#endif
+ rtl_freeMemory(pItem);
+ return sal_True;
+ }
+
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Out osl_isFloppyMounted [may be EBUSY]\n");
+#endif
+
+ rtl_freeMemory(pItem);
+ return sal_False;
+}
+#endif /* IRIX */
+
+
+/* NetBSD floppy functions have to be added here. Until we have done that,
+ * we use the MACOSX definitions for nonexistent floppy.
+ * */
+
+/******************************************************************************
+ *
+ * MAC OS X FLOPPY FUNCTIONS
+ *
+ *****************************************************************************/
+
+#if (defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
+static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
+{
+ return NULL;
+}
+#endif /* MACOSX */
+
+#if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
+static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ return osl_File_E_BUSY;
+}
+#endif /* MACOSX */
+
+#if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
+static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ return osl_File_E_BUSY;
+}
+#endif /* MACOSX */
+
+#if ( defined(NETBSD) || defined(FREEBSD) )
+static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
+{
+ return sal_False;
+}
+#endif /* NETBSD || FREEBSD */
+
+#if ( defined(NETBSD) || defined(FREEBSD) )
+static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
+{
+ return sal_False;
+}
+#endif /* NETBSD || FREEBSD */
+
+
+#ifdef DEBUG_OSL_FILE
+static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
+{
+ if (pItem == 0 )
+ {
+ fprintf(stderr,"NULL Handle\n");
+ return;
+ }
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Invalid Handle]\n");
+#endif
+ return;
+ }
+
+
+ fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
+ fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
+ fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
+
+ return;
+}
+#endif
diff --git a/sal/osl/unx/makefile.mk b/sal/osl/unx/makefile.mk
index 1717d836e..0e728c29d 100644
--- a/sal/osl/unx/makefile.mk
+++ b/sal/osl/unx/makefile.mk
@@ -68,18 +68,20 @@ SLOFILES= $(SLO)$/conditn.obj \
$(SLO)$/security.obj \
$(SLO)$/profile.obj \
$(SLO)$/time.obj \
- $(SLO)$/file.obj \
$(SLO)$/signal.obj \
$(SLO)$/pipe.obj \
$(SLO)$/system.obj \
$(SLO)$/util.obj \
$(SLO)$/tempfile.obj\
+ $(SLO)$/file.obj \
+ $(SLO)$/file_misc.obj \
$(SLO)$/file_url.obj\
$(SLO)$/file_error_transl.obj\
$(SLO)$/file_path_helper.obj\
+ $(SLO)$/file_stat.obj \
+ $(SLO)$/file_volume.obj \
$(SLO)$/uunxapi.obj\
$(SLO)$/process_impl.obj\
- $(SLO)$/file_stat.obj \
$(SLO)$/salinit.obj
#.IF "$(UPDATER)"=="YES"
@@ -96,18 +98,20 @@ OBJFILES= $(OBJ)$/conditn.obj \
$(OBJ)$/security.obj \
$(OBJ)$/profile.obj \
$(OBJ)$/time.obj \
- $(OBJ)$/file.obj \
$(OBJ)$/signal.obj \
$(OBJ)$/pipe.obj \
$(OBJ)$/system.obj \
$(OBJ)$/util.obj \
$(OBJ)$/tempfile.obj\
+ $(OBJ)$/file.obj \
+ $(OBJ)$/file_misc.obj \
$(OBJ)$/file_url.obj\
$(OBJ)$/file_error_transl.obj\
$(OBJ)$/file_path_helper.obj\
+ $(OBJ)$/file_stat.obj \
+ $(OBJ)$/file_volume.obj \
$(OBJ)$/uunxapi.obj\
$(OBJ)$/process_impl.obj\
- $(OBJ)$/file_stat.obj \
$(OBJ)$/salinit.obj
#.ENDIF
diff --git a/sal/osl/w32/MAKEFILE.MK b/sal/osl/w32/MAKEFILE.MK
index e6a338543..cd52ef549 100644
--- a/sal/osl/w32/MAKEFILE.MK
+++ b/sal/osl/w32/MAKEFILE.MK
@@ -78,6 +78,10 @@ SLOFILES= $(SLO)$/conditn.obj \
$(SLO)$/pipe.obj \
$(SLO)$/util.obj \
$(SLO)$/file.obj\
+ $(SLO)$/file_dirvol.obj\
+ $(SLO)$/file_error.obj\
+ $(SLO)$/file_url.obj\
+ $(SLO)$/tempfile.obj\
$(SLO)$/path_helper.obj\
$(SLO)$/procimpl.obj \
$(SLO)$/salinit.obj
@@ -101,6 +105,10 @@ OBJFILES= $(OBJ)$/conditn.obj \
$(OBJ)$/pipe.obj \
$(OBJ)$/util.obj \
$(OBJ)$/file.obj\
+ $(OBJ)$/file_dirvol.obj\
+ $(OBJ)$/file_error.obj\
+ $(OBJ)$/file_url.obj\
+ $(OBJ)$/tempfile.obj\
$(OBJ)$/path_helper.obj\
$(OBJ)$/procimpl.obj \
$(OBJ)$/salinit.obj
diff --git a/sal/osl/w32/file.cxx b/sal/osl/w32/file.cxx
index b7eb4d52b..b8d231a1c 100644
--- a/sal/osl/w32/file.cxx
+++ b/sal/osl/w32/file.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: file.cxx,v $
- * $Revision: 1.19 $
+ * $Revision: 1.0 $
*
* This file is part of OpenOffice.org.
*
@@ -34,26 +34,19 @@
#define UNICODE
#define _UNICODE
#define _WIN32_WINNT 0x0500
-#include "systools\win32\uwinapi.h"
+#include "systools/win32/uwinapi.h"
-#include "path_helper.hxx"
+#include "osl/file.hxx"
-#include "sal/types.h"
+#include "file_url.h"
+#include "file_error.h"
-#include "osl/file.hxx"
#include "osl/diagnose.h"
-#include "rtl/ustring.hxx"
#include "rtl/alloc.h"
-#include "rtl/tencinfo.h"
-#include "osl/thread.h"
-#include "osl/mutex.h"
#include "rtl/byteseq.h"
-#include "osl/time.h"
-//#include <rtl/logfile.h>
-#include <stdio.h>
+#include "rtl/ustring.hxx"
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+#include <stdio.h>
#include <tchar.h>
#ifdef __MINGW32__
@@ -61,2635 +54,700 @@
#include <ctype.h>
#endif
-#include <malloc.h>
#include <algorithm>
#include <limits>
#ifdef max /* conflict w/ std::numeric_limits<T>::max() */
#undef max
#endif
-
-//#####################################################
-// BEGIN global
-//#####################################################
-
-extern "C" oslMutex g_CurrentDirectoryMutex; /* Initialized in dllentry.c */
-oslMutex g_CurrentDirectoryMutex;
-
-//#####################################################
-extern "C" BOOL TimeValueToFileTime(const TimeValue *cpTimeVal, FILETIME *pFTime)
-{
- SYSTEMTIME BaseSysTime;
- FILETIME BaseFileTime;
- FILETIME FTime;
- __int64 localTime;
- BOOL fSuccess = FALSE;
-
- BaseSysTime.wYear = 1970;
- BaseSysTime.wMonth = 1;
- BaseSysTime.wDayOfWeek = 0;
- BaseSysTime.wDay = 1;
- BaseSysTime.wHour = 0;
- BaseSysTime.wMinute = 0;
- BaseSysTime.wSecond = 0;
- BaseSysTime.wMilliseconds = 0;
-
- if (cpTimeVal==NULL)
- return fSuccess;
-
- if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
- {
- __int64 timeValue;
- localTime=cpTimeVal->Seconds*(__int64)10000000+cpTimeVal->Nanosec/100;
- *(__int64 *)&FTime=localTime;
- fSuccess = 0 <= (timeValue= *((__int64 *)&BaseFileTime) + *((__int64 *) &FTime));
- if (fSuccess)
- *(__int64 *)pFTime=timeValue;
- }
- return fSuccess;
-}
-
-//#####################################################
-extern "C" BOOL FileTimeToTimeValue(const FILETIME *cpFTime, TimeValue *pTimeVal)
-{
- SYSTEMTIME BaseSysTime;
- FILETIME BaseFileTime;
- BOOL fSuccess = FALSE; /* Assume failure */
-
- BaseSysTime.wYear = 1970;
- BaseSysTime.wMonth = 1;
- BaseSysTime.wDayOfWeek = 0;
- BaseSysTime.wDay = 1;
- BaseSysTime.wHour = 0;
- BaseSysTime.wMinute = 0;
- BaseSysTime.wSecond = 0;
- BaseSysTime.wMilliseconds = 0;
-
- if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
- {
- __int64 Value;
-
- fSuccess = 0 <= (Value = *((__int64 *)cpFTime) - *((__int64 *)&BaseFileTime));
-
- if ( fSuccess )
- {
- pTimeVal->Seconds = (unsigned long) (Value / 10000000L);
- pTimeVal->Nanosec = (unsigned long)((Value % 10000000L) * 100);
- }
- }
- return fSuccess;
-}
-
-//#####################################################
-extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle(HANDLE hFile)
-{
- if ( IsValidHandle(hFile) )
- return (oslFileHandle)hFile;
- else
- return NULL;
-}
-
-//#####################################################
-// End global
-//#####################################################
-
-
-using namespace osl;
-
-#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) = NULL;}
-#endif
-
-#if OSL_DEBUG_LEVEL > 0
-#define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ? (void)0 : _osl_warnFile( msg, file ) )
-#else
-#define OSL_ENSURE_FILE( cond, msg, file ) ((void)0)
+#ifdef min
+#undef min
#endif
-
-#define PATHTYPE_ERROR 0
-#define PATHTYPE_RELATIVE 1
-#define PATHTYPE_ABSOLUTE_UNC 2
-#define PATHTYPE_ABSOLUTE_LOCAL 3
-#define PATHTYPE_MASK_TYPE 0xFF
-#define PATHTYPE_IS_VOLUME 0x0100
-#define PATHTYPE_IS_SERVER 0x0200
-
-#define VALIDATEPATH_NORMAL 0x0000
-#define VALIDATEPATH_ALLOW_WILDCARDS 0x0001
-#define VALIDATEPATH_ALLOW_ELLIPSE 0x0002
-#define VALIDATEPATH_ALLOW_RELATIVE 0x0004
-#define VALIDATEPATH_ALLOW_UNC 0x0008
-
-#define WSTR_SYSTEM_ROOT_PATH L"\\\\.\\"
-
-typedef struct {
- UINT uType;
-
- union {
- WIN32_FIND_DATA FindData;
- TCHAR cDriveString[MAX_PATH];
- };
- TCHAR szFullPath[MAX_PATH];
- BOOL bFullPathNormalized;
- int nRefCount;
-}DirectoryItem_Impl;
-
-#define DIRECTORYTYPE_LOCALROOT 0
-#define DIRECTORYTYPE_NETROOT 1
-#define DIRECTORYTYPE_NETRESORCE 2
-#define DIRECTORYTYPE_FILESYSTEM 3
-
-#define DIRECTORYITEM_DRIVE 0
-#define DIRECTORYITEM_FILE 1
-#define DIRECTORYITEM_SERVER 2
-
-typedef struct {
- UINT uType;
- union {
- HANDLE hDirectory;
- HANDLE hEnumDrives;
- };
- TCHAR szDirectoryPath[MAX_PATH];
-} Directory_Impl;
-/* Different types of paths */
-typedef enum _PATHTYPE
+//##################################################################
+// File handle implementation
+//##################################################################
+struct FileHandle_Impl
{
- PATHTYPE_SYNTAXERROR = 0,
- PATHTYPE_NETROOT,
- PATHTYPE_NETSERVER,
- PATHTYPE_VOLUME,
- PATHTYPE_FILE
-} PATHTYPE;
-
-
-namespace /* private */
-{
- // forward
- void _osl_warnFile(const char*, rtl_uString*);
- oslFileError SAL_CALL _osl_getFileURLFromSystemPath(rtl_uString* , rtl_uString**);
- DWORD WINAPI IsValidFilePath(rtl_uString*, LPCTSTR*, DWORD, rtl_uString**);
- HANDLE WINAPI OpenLogicalDrivesEnum(void);
- BOOL WINAPI EnumLogicalDrives(HANDLE, LPTSTR);
- BOOL WINAPI CloseLogicalDrivesEnum(HANDLE);
- HANDLE WINAPI OpenDirectory(LPCTSTR);
- BOOL WINAPI CloseDirectory(HANDLE);
- BOOL WINAPI EnumDirectory(HANDLE, LPWIN32_FIND_DATA);
- DWORD WINAPI GetCaseCorrectPathName(LPCTSTR, LPTSTR, DWORD);
- oslFileError SAL_CALL _osl_getSystemPathFromFileURL(rtl_uString*, rtl_uString**, sal_Bool);
-
- /* OS error to errno values mapping table */
- struct errentry {
- unsigned long oscode; /* OS return value */
- int errnocode; /* System V error code */
- };
-
- struct errentry errtable[] = {
- { ERROR_SUCCESS, osl_File_E_None }, /* 0 */
- { ERROR_INVALID_FUNCTION, osl_File_E_INVAL }, /* 1 */
- { ERROR_FILE_NOT_FOUND, osl_File_E_NOENT }, /* 2 */
- { ERROR_PATH_NOT_FOUND, osl_File_E_NOENT }, /* 3 */
- { ERROR_TOO_MANY_OPEN_FILES, osl_File_E_MFILE }, /* 4 */
- { ERROR_ACCESS_DENIED, osl_File_E_ACCES }, /* 5 */
- { ERROR_INVALID_HANDLE, osl_File_E_BADF }, /* 6 */
- { ERROR_ARENA_TRASHED, osl_File_E_NOMEM }, /* 7 */
- { ERROR_NOT_ENOUGH_MEMORY, osl_File_E_NOMEM }, /* 8 */
- { ERROR_INVALID_BLOCK, osl_File_E_NOMEM }, /* 9 */
- { ERROR_BAD_ENVIRONMENT, osl_File_E_2BIG }, /* 10 */
- { ERROR_BAD_FORMAT, osl_File_E_NOEXEC }, /* 11 */
- { ERROR_INVALID_ACCESS, osl_File_E_INVAL }, /* 12 */
- { ERROR_INVALID_DATA, osl_File_E_INVAL }, /* 13 */
- { ERROR_INVALID_DRIVE, osl_File_E_NOENT }, /* 15 */
- { ERROR_CURRENT_DIRECTORY, osl_File_E_ACCES }, /* 16 */
- { ERROR_NOT_SAME_DEVICE, osl_File_E_XDEV }, /* 17 */
- { ERROR_NO_MORE_FILES, osl_File_E_NOENT }, /* 18 */
- { ERROR_NOT_READY, osl_File_E_NOTREADY }, /* 21 */
- { ERROR_LOCK_VIOLATION, osl_File_E_ACCES }, /* 33 */
- { ERROR_BAD_NETPATH, osl_File_E_NOENT }, /* 53 */
- { ERROR_NETWORK_ACCESS_DENIED, osl_File_E_ACCES }, /* 65 */
- { ERROR_BAD_NET_NAME, osl_File_E_NOENT }, /* 67 */
- { ERROR_FILE_EXISTS, osl_File_E_EXIST }, /* 80 */
- { ERROR_CANNOT_MAKE, osl_File_E_ACCES }, /* 82 */
- { ERROR_FAIL_I24, osl_File_E_ACCES }, /* 83 */
- { ERROR_INVALID_PARAMETER, osl_File_E_INVAL }, /* 87 */
- { ERROR_NO_PROC_SLOTS, osl_File_E_AGAIN }, /* 89 */
- { ERROR_DRIVE_LOCKED, osl_File_E_ACCES }, /* 108 */
- { ERROR_BROKEN_PIPE, osl_File_E_PIPE }, /* 109 */
- { ERROR_DISK_FULL, osl_File_E_NOSPC }, /* 112 */
- { ERROR_INVALID_TARGET_HANDLE, osl_File_E_BADF }, /* 114 */
- { ERROR_INVALID_HANDLE, osl_File_E_INVAL }, /* 124 */
- { ERROR_WAIT_NO_CHILDREN, osl_File_E_CHILD }, /* 128 */
- { ERROR_CHILD_NOT_COMPLETE, osl_File_E_CHILD }, /* 129 */
- { ERROR_DIRECT_ACCESS_HANDLE, osl_File_E_BADF }, /* 130 */
- { ERROR_NEGATIVE_SEEK, osl_File_E_INVAL }, /* 131 */
- { ERROR_SEEK_ON_DEVICE, osl_File_E_ACCES }, /* 132 */
- { ERROR_DIR_NOT_EMPTY, osl_File_E_NOTEMPTY }, /* 145 */
- { ERROR_NOT_LOCKED, osl_File_E_ACCES }, /* 158 */
- { ERROR_BAD_PATHNAME, osl_File_E_NOENT }, /* 161 */
- { ERROR_MAX_THRDS_REACHED, osl_File_E_AGAIN }, /* 164 */
- { ERROR_LOCK_FAILED, osl_File_E_ACCES }, /* 167 */
- { ERROR_ALREADY_EXISTS, osl_File_E_EXIST }, /* 183 */
- { ERROR_FILENAME_EXCED_RANGE, osl_File_E_NOENT }, /* 206 */
- { ERROR_NESTING_NOT_ALLOWED, osl_File_E_AGAIN }, /* 215 */
- { ERROR_DIRECTORY, osl_File_E_NOENT }, /* 267 */
- { ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM }, /* 1816 */
- { ERROR_UNEXP_NET_ERR, osl_File_E_NETWORK } /* 59 */
- };
-
- /* The following two constants must be the minimum and maximum
- values in the (contiguous) range of osl_File_E_xec Failure errors. */
- #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
- #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
-
- /* These are the low and high value in the range of errors that are
- access violations */
- #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
- #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
-
- //#####################################################
- oslFileError MapError(DWORD dwError)
- {
- for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i )
- {
- if (dwError == errtable[i].oscode)
- return static_cast<oslFileError>(errtable[i].errnocode);
- }
+ HANDLE m_hFile;
- /* The error code wasn't in the table. We check for a range of
- osl_File_E_ACCES errors or exec failure errors (ENOEXEC).
- Otherwise osl_File_E_INVAL is returned. */
- if ( dwError >= MIN_EACCES_RANGE && dwError <= MAX_EACCES_RANGE)
- return osl_File_E_ACCES;
- else if ( dwError >= MIN_EXEC_ERROR && dwError <= MAX_EXEC_ERROR)
- return osl_File_E_NOEXEC;
- else
- return osl_File_E_INVAL;
- }
-
- //#####################################################
- oslFileError SAL_CALL osl_openLocalRoot(
- rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
+ /** State
+ */
+ enum StateBits
{
- rtl_uString *strSysPath = NULL;
- oslFileError error;
-
- if ( !pDirectory )
- return osl_File_E_INVAL;
-
- *pDirectory = NULL;
-
- error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysPath, sal_False );
-
- if ( osl_File_E_None == error )
- {
- Directory_Impl *pDirImpl;
-
- pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory( sizeof(Directory_Impl)));
- _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysPath)) );
-
- /* Append backslash if neccessary */
-
- /* @@@ToDo
- use function ensure backslash
- */
- if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' )
- _tcscat( pDirImpl->szDirectoryPath, L"\\" );
+ STATE_SEEKABLE = 1, /* open() sets, iff regular file */
+ STATE_READABLE = 2, /* open() sets, read() requires */
+ STATE_WRITEABLE = 4, /* open() sets, write() requires */
+ STATE_MODIFIED = 8 /* write() sets, flush() resets */
+ };
+ int m_state;
- pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
- pDirImpl->hEnumDrives = OpenLogicalDrivesEnum();
+ sal_uInt64 m_size; /* file size */
+ LONGLONG m_offset; /* physical offset from begin of file */
+ LONGLONG m_filepos; /* logical offset from begin of file */
- /* @@@ToDo
- Use IsValidHandle(...)
- */
- if ( pDirImpl->hEnumDrives != INVALID_HANDLE_VALUE )
- {
- *pDirectory = (oslDirectory)pDirImpl;
- error = osl_File_E_None;
- }
- else
- {
- if ( pDirImpl )
- rtl_freeMemory(pDirImpl);
+ LONGLONG m_bufptr; /* buffer offset from begin of file */
+ SIZE_T m_buflen; /* buffer filled [0, m_bufsiz - 1] */
- error = MapError( GetLastError() );
- }
+ SIZE_T m_bufsiz;
+ sal_uInt8 * m_buffer;
- rtl_uString_release( strSysPath );
- }
- return error;
- }
+ explicit FileHandle_Impl (HANDLE hFile);
+ ~FileHandle_Impl();
- //#####################################################
- oslFileError SAL_CALL osl_openFileDirectory(
- rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
- {
- // MT: Done in osl_openDirectory!
-// rtl_uString *strSysPath = NULL;
- oslFileError error;
-
- //MT: Not done in osl_openNetworkServer, why here?
- if ( !pDirectory )
- return osl_File_E_INVAL;
+ static void* operator new(size_t n);
+ static void operator delete(void * p, size_t);
+ static SIZE_T getpagesize();
- *pDirectory = NULL;
+ sal_uInt64 getPos() const;
+ oslFileError setPos (sal_uInt64 uPos);
- // MT: Done in osl_openDirectory!
-// error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysPath, sal_False );
-// if ( osl_File_E_None == error )
- {
- Directory_Impl *pDirImpl;
+ sal_uInt64 getSize() const;
- pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
- _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strDirectoryPath)) );
+ oslFileError readAt (
+ LONGLONG nOffset,
+ void * pBuffer,
+ DWORD nBytesRequested,
+ sal_uInt64 * pBytesRead);
- /* Append backslash if neccessary */
+ oslFileError writeAt (
+ LONGLONG nOffset,
+ void const * pBuffer,
+ DWORD nBytesToWrite,
+ sal_uInt64 * pBytesWritten);
- /* @@@ToDo
- use function ensure backslash
- */
- if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' )
- _tcscat( pDirImpl->szDirectoryPath, L"\\" );
- // MT: ???
- // GetCaseCorrectPathName( pDirImpl->szDirectoryPath, pDirImpl->szDirectoryPath, sizeof(pDirImpl->szDirectoryPath) );
+ oslFileError readFileAt (
+ LONGLONG nOffset,
+ void * pBuffer,
+ sal_uInt64 uBytesRequested,
+ sal_uInt64 * pBytesRead);
- pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
- pDirImpl->hDirectory = OpenDirectory( pDirImpl->szDirectoryPath );
+ oslFileError writeFileAt (
+ LONGLONG nOffset,
+ void const * pBuffer,
+ sal_uInt64 uBytesToWrite,
+ sal_uInt64 * pBytesWritten);
- if ( pDirImpl->hDirectory )
- {
- *pDirectory = (oslDirectory)pDirImpl;
- error = osl_File_E_None;
- }
- else
- {
- if ( pDirImpl )
- rtl_freeMemory(pDirImpl);
+ oslFileError readLineAt (
+ LONGLONG nOffset,
+ sal_Sequence ** ppSequence,
+ sal_uInt64 * pBytesRead);
- error = MapError( GetLastError() );
- }
+ oslFileError writeSequence_Impl (
+ sal_Sequence ** ppSequence,
+ SIZE_T * pnOffset,
+ const void * pBuffer,
+ SIZE_T nBytes);
-// rtl_uString_release( strSysPath );
- }
- return error;
- }
+ oslFileError syncFile();
- typedef struct tagDIRECTORY
- {
- HANDLE hFind;
- WIN32_FIND_DATA aFirstData;
- } DIRECTORY, *PDIRECTORY, FAR *LPDIRECTORY;
-
- //#####################################################
- HANDLE WINAPI OpenDirectory(LPCTSTR lpszPath)
+ /** Buffer cache / allocator.
+ */
+ class Allocator
{
- LPDIRECTORY pDirectory = (LPDIRECTORY)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY));
-
- if (pDirectory)
- {
- TCHAR szFileMask[MAX_PATH];
- int nLen;
+ rtl_cache_type * m_cache;
+ SIZE_T m_bufsiz;
- _tcscpy( szFileMask, lpszPath );
- nLen = _tcslen( szFileMask );
+ Allocator (Allocator const &);
+ Allocator & operator= (Allocator const &);
- if (nLen && szFileMask[nLen-1] != '\\')
- _tcscat(szFileMask, TEXT("\\*.*"));
- else
- _tcscat(szFileMask, TEXT("*.*"));
+ public:
+ static Allocator & get();
- pDirectory->hFind = FindFirstFile(szFileMask, &pDirectory->aFirstData);
+ void allocate (sal_uInt8 ** ppBuffer, SIZE_T * pnSize);
+ void deallocate (sal_uInt8 * pBuffer);
- if (!IsValidHandle(pDirectory->hFind))
- {
- if ( GetLastError() != ERROR_NO_MORE_FILES )
- {
- HeapFree(GetProcessHeap(), 0, pDirectory);
- pDirectory = NULL;
- }
- }
- }
- return (HANDLE)pDirectory;
- }
-
- //#####################################################
- BOOL WINAPI CloseDirectory(HANDLE hDirectory)
- {
- BOOL fSuccess = FALSE;
- LPDIRECTORY pDirectory = (LPDIRECTORY)hDirectory;
+ protected:
+ Allocator();
+ ~Allocator();
+ };
+};
- if (pDirectory)
- {
- if (IsValidHandle(pDirectory->hFind))
- fSuccess = FindClose(pDirectory->hFind);
+FileHandle_Impl::Allocator &
+FileHandle_Impl::Allocator::get()
+{
+ static Allocator g_aBufferAllocator;
+ return g_aBufferAllocator;
+}
- fSuccess = HeapFree(GetProcessHeap(), 0, pDirectory) && fSuccess;
- }
- else
- SetLastError(ERROR_INVALID_HANDLE);
+FileHandle_Impl::Allocator::Allocator()
+ : m_cache (0),
+ m_bufsiz (0)
+{
+ SIZE_T const pagesize = FileHandle_Impl::getpagesize();
+ m_cache = rtl_cache_create (
+ "osl_file_buffer_cache", pagesize, 0, 0, 0, 0, 0, 0, 0);
+ if (0 != m_cache)
+ m_bufsiz = pagesize;
+}
- return fSuccess;
- }
+FileHandle_Impl::Allocator::~Allocator()
+{
+ rtl_cache_destroy(m_cache), m_cache = 0;
+}
- //#####################################################
- BOOL WINAPI EnumDirectory(HANDLE hDirectory, LPWIN32_FIND_DATA pFindData)
- {
- BOOL fSuccess = FALSE;
- LPDIRECTORY pDirectory = (LPDIRECTORY)hDirectory;
+void FileHandle_Impl::Allocator::allocate (sal_uInt8 ** ppBuffer, SIZE_T * pnSize)
+{
+ OSL_PRECOND((0 != ppBuffer) && (0 != pnSize), "FileHandle_Impl::Allocator::allocate(): contract violation");
+ *ppBuffer = static_cast< sal_uInt8* >(rtl_cache_alloc(m_cache)), *pnSize = m_bufsiz;
+}
- if ( pDirectory )
- {
- BOOL fValid;
+void FileHandle_Impl::Allocator::deallocate (sal_uInt8 * pBuffer)
+{
+ if (0 != pBuffer)
+ rtl_cache_free (m_cache, pBuffer);
+}
- do
- {
- if ( pDirectory->aFirstData.cFileName[0] )
- {
- *pFindData = pDirectory->aFirstData;
- fSuccess = TRUE;
- pDirectory->aFirstData.cFileName[0] = 0;
- }
- else if ( IsValidHandle( pDirectory->hFind ) )
- fSuccess = FindNextFile( pDirectory->hFind, pFindData );
- else
- {
- fSuccess = FALSE;
- SetLastError( ERROR_NO_MORE_FILES );
- }
+FileHandle_Impl::FileHandle_Impl(HANDLE hFile)
+ : m_hFile (hFile),
+ m_state (STATE_READABLE | STATE_WRITEABLE),
+ m_size (0),
+ m_offset (0),
+ m_filepos (0),
+ m_bufptr (-1),
+ m_buflen (0),
+ m_bufsiz (0),
+ m_buffer (0)
+{
+ Allocator::get().allocate (&m_buffer, &m_bufsiz);
+ if (m_buffer != 0)
+ memset (m_buffer, 0, m_bufsiz);
+}
- fValid = fSuccess && _tcscmp( TEXT("."), pFindData->cFileName ) != 0 && _tcscmp( TEXT(".."), pFindData->cFileName ) != 0;
+FileHandle_Impl::~FileHandle_Impl()
+{
+ Allocator::get().deallocate (m_buffer), m_buffer = 0;
+}
- } while( fSuccess && !fValid );
- }
- else
- SetLastError( ERROR_INVALID_HANDLE );
+void * FileHandle_Impl::operator new(size_t n)
+{
+ return rtl_allocateMemory(n);
+}
- return fSuccess;
- }
+void FileHandle_Impl::operator delete(void * p, size_t)
+{
+ rtl_freeMemory(p);
+}
- //#####################################################
- oslFileError SAL_CALL osl_openNetworkServer(rtl_uString *strSysDirPath, oslDirectory *pDirectory)
- {
- NETRESOURCEW aNetResource;
- HANDLE hEnum;
- DWORD dwError;
+SIZE_T FileHandle_Impl::getpagesize()
+{
+ SYSTEM_INFO info;
+ ::GetSystemInfo (&info);
+ return sal::static_int_cast< SIZE_T >(info.dwPageSize);
+}
- ZeroMemory( &aNetResource, sizeof(aNetResource) );
+sal_uInt64 FileHandle_Impl::getPos() const
+{
+ return sal::static_int_cast< sal_uInt64 >(m_filepos);
+}
- aNetResource.lpRemoteName = reinterpret_cast<LPWSTR>(strSysDirPath->buffer);
+oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos)
+{
+ m_filepos = sal::static_int_cast< LONGLONG >(uPos);
+ return osl_File_E_None;
+}
- dwError = WNetOpenEnumW(
- RESOURCE_GLOBALNET,
- RESOURCETYPE_DISK,
- RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER,
- &aNetResource,
- &hEnum );
+sal_uInt64 FileHandle_Impl::getSize() const
+{
+ LONGLONG bufend = std::max((LONGLONG)(0), m_bufptr) + m_buflen;
+ return std::max(m_size, sal::static_int_cast< sal_uInt64 >(bufend));
+}
- if ( ERROR_SUCCESS == dwError )
- {
- Directory_Impl *pDirImpl;
+oslFileError FileHandle_Impl::readAt (
+ LONGLONG nOffset,
+ void * pBuffer,
+ DWORD nBytesRequested,
+ sal_uInt64 * pBytesRead)
+{
+ OSL_PRECOND(m_state & STATE_SEEKABLE, "FileHandle_Impl::readAt(): not seekable");
+ if (!(m_state & STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
- pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
- pDirImpl->uType = DIRECTORYTYPE_NETROOT;
- pDirImpl->hDirectory = hEnum;
- *pDirectory = (oslDirectory)pDirImpl;
- }
- return MapError( dwError );
- }
+ OSL_PRECOND(m_state & STATE_READABLE, "FileHandle_Impl::readAt(): not readable");
+ if (!(m_state & STATE_READABLE))
+ return osl_File_E_BADF;
- //#####################################################
- oslFileError SAL_CALL osl_getNextNetResource(
- oslDirectory Directory,
- oslDirectoryItem *pItem,
- sal_uInt32 uHint )
+ if (nOffset != m_offset)
{
- Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
- DirectoryItem_Impl *pItemImpl = NULL;
- BYTE buffer[16384];
- LPNETRESOURCEW lpNetResource = (LPNETRESOURCEW)buffer;
- DWORD dwError, dwCount, dwBufSize;
-
- uHint = uHint; /* to get no warning */
-
- if ( !pItem )
- return osl_File_E_INVAL;
-
- *pItem = NULL;
-
- if ( !pDirImpl )
- return osl_File_E_INVAL;
-
- dwCount = 1;
- dwBufSize = sizeof(buffer);
- dwError = WNetEnumResource( pDirImpl->hDirectory, &dwCount, lpNetResource, &dwBufSize );
-
- switch ( dwError )
- {
- case NO_ERROR:
- case ERROR_MORE_DATA:
- {
- pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
- if ( !pItemImpl )
- return osl_File_E_NOMEM;
-
- ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
- pItemImpl->uType = DIRECTORYITEM_DRIVE;
- osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
-
- wcscpy( pItemImpl->cDriveString, lpNetResource->lpRemoteName );
-
- *pItem = pItemImpl;
- }
- return osl_File_E_None;
- case ERROR_NO_MORE_ITEMS:
- return osl_File_E_NOENT;
- default:
- return MapError( dwError );
- }
+ LARGE_INTEGER liOffset; liOffset.QuadPart = nOffset;
+ if (!::SetFilePointerEx(m_hFile, liOffset, 0, FILE_BEGIN))
+ return oslTranslateFileError( GetLastError() );
+ m_offset = nOffset;
}
- //#####################################################
- oslFileError SAL_CALL osl_getNextDrive(
- oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
- {
- Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
- DirectoryItem_Impl *pItemImpl = NULL;
- BOOL fSuccess;
-
- uHint = uHint; /* avoid warnings */
-
- if ( !pItem )
- return osl_File_E_INVAL;
-
- *pItem = NULL;
-
- if ( !pDirImpl )
- return osl_File_E_INVAL;
+ DWORD dwDone = 0;
+ if (!::ReadFile(m_hFile, pBuffer, nBytesRequested, &dwDone, 0))
+ return oslTranslateFileError( GetLastError() );
+ m_offset += dwDone;
- pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
- if ( !pItemImpl )
- return osl_File_E_NOMEM;
+ *pBytesRead = dwDone;
+ return osl_File_E_None;
+}
+oslFileError FileHandle_Impl::writeAt (
+ LONGLONG nOffset,
+ void const * pBuffer,
+ DWORD nBytesToWrite,
+ sal_uInt64 * pBytesWritten)
+{
+ OSL_PRECOND(m_state & STATE_SEEKABLE, "FileHandle_Impl::writeAt(): not seekable");
+ if (!(m_state & STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
- ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
- pItemImpl->uType = DIRECTORYITEM_DRIVE;
- osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
- fSuccess = EnumLogicalDrives( pDirImpl->hEnumDrives, pItemImpl->cDriveString );
+ OSL_PRECOND(m_state & STATE_WRITEABLE, "FileHandle_Impl::writeAt(): not writeable");
+ if (!(m_state & STATE_WRITEABLE))
+ return osl_File_E_BADF;
- if ( fSuccess )
- {
- *pItem = pItemImpl;
- return osl_File_E_None;
- }
- else
- {
- rtl_freeMemory( pItemImpl );
- return MapError( GetLastError() );
- }
- }
-
- //#####################################################
- oslFileError SAL_CALL osl_getNextFileItem(
- oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
+ if (nOffset != m_offset)
{
- Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
- DirectoryItem_Impl *pItemImpl = NULL;
- BOOL fFound;
-
- uHint = uHint; /* avoid warnings */
-
- if ( !pItem )
- return osl_File_E_INVAL;
-
- *pItem = NULL;
-
- if ( !pDirImpl )
- return osl_File_E_INVAL;
-
- pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
- if ( !pItemImpl )
- return osl_File_E_NOMEM;
-
- memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
- fFound = EnumDirectory( pDirImpl->hDirectory, &pItemImpl->FindData );
-
- if ( fFound )
- {
- pItemImpl->uType = DIRECTORYITEM_FILE;
- pItemImpl->nRefCount = 1;
- _tcscpy( pItemImpl->szFullPath, pDirImpl->szDirectoryPath );
- _tcscat( pItemImpl->szFullPath, pItemImpl->FindData.cFileName );
- pItemImpl->bFullPathNormalized = FALSE;
- *pItem = (oslDirectoryItem)pItemImpl;
- return osl_File_E_None;
- }
- else
- {
- rtl_freeMemory( pItemImpl );
- return MapError( GetLastError() );
- }
+ LARGE_INTEGER liOffset; liOffset.QuadPart = nOffset;
+ if (!::SetFilePointerEx (m_hFile, liOffset, 0, FILE_BEGIN))
+ return oslTranslateFileError( GetLastError() );
+ m_offset = nOffset;
}
+
+ DWORD dwDone = 0;
+ if (!::WriteFile(m_hFile, pBuffer, nBytesToWrite, &dwDone, 0))
+ return oslTranslateFileError( GetLastError() );
+ m_offset += dwDone;
- //#####################################################
- oslFileError SAL_CALL osl_getDriveInfo(
- oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
- {
- DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
- TCHAR cDrive[3] = TEXT("A:");
- TCHAR cRoot[4] = TEXT("A:\\");
-
- if ( !pItemImpl )
- return osl_File_E_INVAL;
-
- pStatus->uValidFields = 0;
-
- cDrive[0] = pItemImpl->cDriveString[0];
- cRoot[0] = pItemImpl->cDriveString[0];
-
- if ( uFieldMask & osl_FileStatus_Mask_FileName )
- {
- if ( pItemImpl->cDriveString[0] == '\\' &&
- pItemImpl->cDriveString[1] == '\\' )
- {
- LPCWSTR lpFirstBkSlash = wcschr( &pItemImpl->cDriveString[2], '\\' );
-
- if ( lpFirstBkSlash && lpFirstBkSlash[1] )
- {
- LPCWSTR lpLastBkSlash = wcschr( &lpFirstBkSlash[1], '\\' );
-
- if ( lpLastBkSlash )
- rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]), lpLastBkSlash - lpFirstBkSlash - 1 );
- else
- rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]) );
- pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
- }
- }
- else switch ( GetDriveType( cRoot ) )
- {
- case DRIVE_REMOTE:
- {
- TCHAR szBuffer[1024];
- DWORD dwBufsize = ELEMENTS_OF_ARRAY(szBuffer);
- DWORD dwResult = WNetGetConnection( cDrive, szBuffer, &dwBufsize );
-
- if ( NO_ERROR == dwResult )
- {
- TCHAR szFileName[ELEMENTS_OF_ARRAY(szBuffer) + 16];
-
- swprintf( szFileName, L"%s [%s]", cDrive, szBuffer );
- rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
- }
- else
- rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
- }
- pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
- break;
- case DRIVE_FIXED:
- {
- TCHAR szVolumeNameBuffer[1024];
-
- if ( GetVolumeInformation( cRoot, szVolumeNameBuffer, ELEMENTS_OF_ARRAY(szVolumeNameBuffer), NULL, NULL, NULL, NULL, 0 ) )
- {
- TCHAR szFileName[ELEMENTS_OF_ARRAY(szVolumeNameBuffer) + 16];
-
- swprintf( szFileName, L"%s [%s]", cDrive, szVolumeNameBuffer );
- rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
- }
- else
- rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
- }
- pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
- break;
- case DRIVE_CDROM:
- case DRIVE_REMOVABLE:
- pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
- rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cRoot) );
- break;
- case DRIVE_UNKNOWN:
- default:
- break;
- }
- }
-
- pStatus->eType = osl_File_Type_Volume;
- pStatus->uValidFields |= osl_FileStatus_Mask_Type;
+ m_size = std::max(m_size, sal::static_int_cast< sal_uInt64 >(m_offset));
- if ( uFieldMask & osl_FileStatus_Mask_FileURL )
- {
- rtl_uString *ustrSystemPath = NULL;
+ *pBytesWritten = dwDone;
+ return osl_File_E_None;
+}
- rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->cDriveString) );
- osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
- rtl_uString_release( ustrSystemPath );
- pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
- }
- return osl_File_E_None;
- }
+oslFileError FileHandle_Impl::readFileAt (
+ LONGLONG nOffset,
+ void * pBuffer,
+ sal_uInt64 uBytesRequested,
+ sal_uInt64 * pBytesRead)
+{
+ static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max();
+ if (g_limit_dword < uBytesRequested)
+ return osl_File_E_OVERFLOW;
+ DWORD nBytesRequested = sal::static_int_cast< DWORD >(uBytesRequested);
- //#####################################################
- oslFileError SAL_CALL osl_getServerInfo(
- oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask )
+ if (0 == (m_state & STATE_SEEKABLE))
{
- DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
-
- if ( !pItemImpl )
- return osl_File_E_INVAL;
-
- pStatus->uValidFields = 0;
-
- // pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
-
- // if ( _tcscmp( pItemImpl->FindData.cFileName, TEXT(".") ) == 0 )
- // rtl_uString_newFromAscii( &pStatus->ustrFileName, "/" );
- // else
- // rtl_uString_newFromStr( &pStatus->ustrFileName, pItemImpl->FindData.cFileName );
-
- pStatus->eType = osl_File_Type_Directory;
- pStatus->uValidFields |= osl_FileStatus_Mask_Type;
-
- if ( uFieldMask & osl_FileStatus_Mask_FileURL )
- {
- rtl_uString *ustrSystemPath = NULL;
-
- rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) );
- osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
- rtl_uString_release( ustrSystemPath );
- pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
- }
+ // not seekable (pipe)
+ DWORD dwDone = 0;
+ if (!::ReadFile(m_hFile, pBuffer, nBytesRequested, &dwDone, 0))
+ return oslTranslateFileError( GetLastError() );
+ *pBytesRead = dwDone;
return osl_File_E_None;
}
-
- typedef struct tagDRIVEENUM {
- LPCTSTR lpIdent;
- TCHAR cBuffer[/*('Z' - 'A' + 1) * sizeof("A:\\") + 1*/256];
- LPCTSTR lpCurrent;
- } DRIVEENUM, * PDRIVEENUM, FAR * LPDRIVEENUM;
-
- //#####################################################
- HANDLE WINAPI OpenLogicalDrivesEnum(void)
+ else if (0 == m_buffer)
{
- LPDRIVEENUM pEnum = NULL;
-
- pEnum = (LPDRIVEENUM)HeapAlloc( GetProcessHeap(), 0, sizeof(DRIVEENUM) );
-
- if ( pEnum )
- {
- DWORD dwNumCopied = GetLogicalDriveStrings( (sizeof(pEnum->cBuffer) - 1) / sizeof(TCHAR), pEnum->cBuffer );
-
- if ( dwNumCopied && dwNumCopied < sizeof(pEnum->cBuffer) / sizeof(TCHAR) )
- {
- pEnum->lpCurrent = pEnum->cBuffer;
- pEnum->lpIdent = L"tagDRIVEENUM";
- }
- else
- {
- HeapFree( GetProcessHeap(), 0, pEnum );
- pEnum = NULL;
- }
- }
- return pEnum ? (HANDLE)pEnum : INVALID_HANDLE_VALUE;
+ // not buffered
+ return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
}
-
- //#####################################################
- BOOL WINAPI EnumLogicalDrives(HANDLE hEnum, LPTSTR lpBuffer)
+ else
{
- BOOL fSuccess = FALSE;
- LPDRIVEENUM pEnum = (LPDRIVEENUM)hEnum;
-
- if ( pEnum )
+ sal_uInt8 * buffer = static_cast< sal_uInt8* >(pBuffer);
+ for (*pBytesRead = 0; nBytesRequested > 0; )
{
- int nLen = _tcslen( pEnum->lpCurrent );
+ LONGLONG const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
+ SIZE_T const bufpos = (nOffset % m_bufsiz);
- if ( nLen )
+ if (bufptr != m_bufptr)
{
- CopyMemory( lpBuffer, pEnum->lpCurrent, (nLen + 1) * sizeof(TCHAR) );
- pEnum->lpCurrent += nLen + 1;
- fSuccess = TRUE;
- }
- else
- SetLastError( ERROR_NO_MORE_FILES );
- }
- else
- SetLastError( ERROR_INVALID_HANDLE );
-
- return fSuccess;
- }
-
- //#####################################################
- BOOL WINAPI CloseLogicalDrivesEnum(HANDLE hEnum)
- {
- BOOL fSuccess = FALSE;
- LPDRIVEENUM pEnum = (LPDRIVEENUM)hEnum;
-
- if ( pEnum )
- {
- HeapFree( GetProcessHeap(), 0, pEnum );
- fSuccess = TRUE;
- }
- else
- SetLastError( ERROR_INVALID_HANDLE );
+ // flush current buffer
+ oslFileError result = syncFile();
+ if (result != osl_File_E_None)
+ return (result);
- return fSuccess;
- }
-
- //#####################################################
- //Undocumented in SHELL32.DLL ordinal 35
- BOOL WINAPI PathRemoveFileSpec(LPTSTR lpPath)
- {
- BOOL fSuccess = FALSE; // Assume failure
- LPTSTR lpLastBkSlash = _tcsrchr( lpPath, '\\' );
- LPTSTR lpLastSlash = _tcsrchr( lpPath, '/' );
- LPTSTR lpLastDelimiter = lpLastSlash > lpLastBkSlash ? lpLastSlash : lpLastBkSlash;
-
- if ( lpLastDelimiter )
- {
- if ( 0 == *(lpLastDelimiter + 1) )
- {
- if ( lpLastDelimiter > lpPath && *(lpLastDelimiter - 1) != ':' )
+ if (nBytesRequested >= m_bufsiz)
{
- *lpLastDelimiter = 0;
- fSuccess = TRUE;
+ // buffer too small, read through from file
+ sal_uInt64 uDone = 0;
+ result = readAt (nOffset, &(buffer[*pBytesRead]), nBytesRequested, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+
+ nBytesRequested -= sal::static_int_cast< DWORD >(uDone), *pBytesRead += uDone;
+ return osl_File_E_None;
}
- }
- else
- {
- *(++lpLastDelimiter) = 0;
- fSuccess = TRUE;
- }
- }
- return fSuccess;
- }
-
- //#####################################################
- // Undocumented in SHELL32.DLL ordinal 32
- LPTSTR WINAPI PathAddBackslash(LPTSTR lpPath)
- {
- LPTSTR lpEndPath = NULL;
-
- if ( lpPath )
- {
- int nLen = _tcslen(lpPath);
- if ( !nLen || lpPath[nLen-1] != '\\' && lpPath[nLen-1] != '/' && nLen < MAX_PATH - 1 )
- {
- lpEndPath = lpPath + nLen;
- *lpEndPath++ = '\\';
- *lpEndPath = 0;
+ // update buffer (pointer)
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
}
- }
- return lpEndPath;
- }
-
-#if 1
- //#####################################################
- // Same as GetLongPathName but also 95/NT4
- DWORD WINAPI GetCaseCorrectPathNameEx(
- LPCTSTR lpszShortPath, // file name
- LPTSTR lpszLongPath, // path buffer
- DWORD cchBuffer, // size of path buffer
- DWORD nSkipLevels
- )
- {
-// log file doesn't work, because initialization of rtl log init() calls this method...
-// RTL_LOGFILE_TRACE1( "SAL: GetCaseCorrectPathNameEx: %s (Skip:%n)", lpszShortPath,nSkipLevels );
-
- TCHAR szPath[MAX_PATH];
- BOOL fSuccess;
-
- cchBuffer = cchBuffer; /* avoid warnings */
-
- _tcscpy( szPath, lpszShortPath );
-
- fSuccess = PathRemoveFileSpec( szPath );
-
- if ( fSuccess )
- {
- int nLen = _tcslen( szPath );
- LPCTSTR lpszFileSpec = lpszShortPath + nLen;
- BOOL bSkipThis;
-
- if ( 0 == _tcscmp( lpszFileSpec, TEXT("..") ) )
+ if (bufpos >= m_buflen)
{
- bSkipThis = TRUE;
- nSkipLevels += 1;
+ // end of file
+ return osl_File_E_None;
}
- else if (
- 0 == _tcscmp( lpszFileSpec, TEXT(".") ) ||
- 0 == _tcscmp( lpszFileSpec, TEXT("\\") ) ||
- 0 == _tcscmp( lpszFileSpec, TEXT("/") )
- )
- {
- bSkipThis = TRUE;
- }
- else if ( nSkipLevels )
- {
- bSkipThis = TRUE;
- nSkipLevels--;
- }
- else
- bSkipThis = FALSE;
-
- GetCaseCorrectPathNameEx( szPath, szPath, MAX_PATH, nSkipLevels );
- PathAddBackslash( szPath );
-
- /* Analyze parent if not only a trailing backslash was cutted but a real file spec */
- if ( !bSkipThis )
- {
- WIN32_FIND_DATA aFindFileData;
- HANDLE hFind = FindFirstFile( lpszShortPath, &aFindFileData );
-
- if ( IsValidHandle(hFind) )
- {
- _tcscat( szPath, aFindFileData.cFileName[0] ? aFindFileData.cFileName : aFindFileData.cAlternateFileName );
-
- FindClose( hFind );
- }
- else
- return 0;
- }
- }
- else
- {
- /* File specification can't be removed therefore the short path is either a drive
- or a network share. If still levels to skip are left, the path specification
- tries to travel below the file system root */
- if ( nSkipLevels )
- return 0;
-
- _tcsupr( szPath );
+ SIZE_T const bytes = std::min(m_buflen - bufpos, nBytesRequested);
+ memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes);
+ nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes;
}
-
- _tcscpy( lpszLongPath, szPath );
-
- return _tcslen( lpszLongPath );
- }
-#endif
-
-#if 0
- inline size_t wcstoupper( LPWSTR lpStr )
- {
- size_t nLen = wcslen( lpStr );
-
- for ( LPWSTR p = lpStr; p < lpStr + nLen; p++ )
- {
- *p = towupper(*p);
- }
-
- return nLen;
+ return osl_File_E_None;
}
+}
-#endif
+oslFileError FileHandle_Impl::writeFileAt (
+ LONGLONG nOffset,
+ void const * pBuffer,
+ sal_uInt64 uBytesToWrite,
+ sal_uInt64 * pBytesWritten)
+{
+ static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max();
+ if (g_limit_dword < uBytesToWrite)
+ return osl_File_E_OVERFLOW;
+ DWORD nBytesToWrite = sal::static_int_cast< DWORD >(uBytesToWrite);
- //#####################################################
- DWORD WINAPI GetCaseCorrectPathName(
- LPCTSTR lpszShortPath, // file name
- LPTSTR lpszLongPath, // path buffer
- DWORD cchBuffer // size of path buffer
- )
-#if 0
+ if (0 == (m_state & STATE_SEEKABLE))
{
- /* Special handling for "\\.\" as system root */
- if ( lpszShortPath && 0 == wcscmp( lpszShortPath, WSTR_SYSTEM_ROOT_PATH ) )
- {
- if ( cchBuffer >= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) )
- {
- wcscpy( lpszLongPath, WSTR_SYSTEM_ROOT_PATH );
- return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1;
- }
- else
- return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH);
- }
- else
- {
- DWORD nSrcLen = wcslen( lpszShortPath );
-
- if ( cchBuffer > nSrcLen )
- {
- wcscpy( lpszLongPath, lpszShortPath );
- wcstoupper( lpszLongPath );
- }
- else
- nSrcLen++;
-
- return nSrcLen;
- }
+ // not seekable (pipe)
+ DWORD dwDone = 0;
+ if (!::WriteFile(m_hFile, pBuffer, nBytesToWrite, &dwDone, 0))
+ return oslTranslateFileError( GetLastError() );
+ *pBytesWritten = dwDone;
+ return osl_File_E_None;
}
-#else
+ else if (0 == m_buffer)
{
- /* Special handling for "\\.\" as system root */
- if ( lpszShortPath && 0 == wcscmp( lpszShortPath, WSTR_SYSTEM_ROOT_PATH ) )
- {
- if ( cchBuffer >= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) )
- {
- wcscpy( lpszLongPath, WSTR_SYSTEM_ROOT_PATH );
- return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1;
- }
- else
- return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1;
- }
- else
- return GetCaseCorrectPathNameEx( lpszShortPath, lpszLongPath, cchBuffer, 0 );
+ // not buffered
+ return writeAt(nOffset, pBuffer, nBytesToWrite, pBytesWritten);
}
-
-#endif
-
- //#####################################################
- #define CHARSET_SEPARATOR TEXT("\\/")
-
- BOOL WINAPI IsValidFilePathComponent(
- LPCTSTR lpComponent, LPCTSTR *lppComponentEnd, DWORD dwFlags)
+ else
{
- LPCTSTR lpComponentEnd = NULL;
- LPCTSTR lpCurrent = lpComponent;
- BOOL fValid = TRUE; /* Assume success */
- TCHAR cLast = 0;
-
- /* Path component length must not exceed MAX_PATH */
-
- while ( !lpComponentEnd && lpCurrent && lpCurrent - lpComponent < MAX_PATH )
+ sal_uInt8 const * buffer = static_cast< sal_uInt8 const* >(pBuffer);
+ for (*pBytesWritten = 0; nBytesToWrite > 0; )
{
- switch ( *lpCurrent )
+ LONGLONG const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
+ SIZE_T const bufpos = (nOffset % m_bufsiz);
+ if (bufptr != m_bufptr)
{
- /* Both backslash and slash determine the end of a path component */
- case '\0':
- case '/':
- case '\\':
- switch ( cLast )
- {
- /* Component must not end with '.' or blank and can't be empty */
-
- case '.':
- if ( dwFlags & VALIDATEPATH_ALLOW_ELLIPSE )
- {
- if ( 1 == lpCurrent - lpComponent )
- {
- /* Current directory is O.K. */
- lpComponentEnd = lpCurrent;
- break;
- }
- else if ( 2 == lpCurrent - lpComponent && '.' == *lpComponent )
- {
- /* Parent directory is O.K. */
- lpComponentEnd = lpCurrent;
- break;
- }
- }
- case 0:
- case ' ':
- lpComponentEnd = lpCurrent - 1;
- fValid = FALSE;
- break;
- default:
- lpComponentEnd = lpCurrent;
- break;
- }
- break;
- /* '?' and '*' are valid wildcards but not valid file name characters */
- case '?':
- case '*':
- if ( dwFlags & VALIDATEPATH_ALLOW_WILDCARDS )
- break;
- /* The following characters are reserved */
- case '<':
- case '>':
- case '\"':
- case '|':
- case ':':
- lpComponentEnd = lpCurrent;
- fValid = FALSE;
- break;
- default:
- /* Characters below ASCII 32 are not allowed */
- if ( *lpCurrent < ' ' )
- {
- lpComponentEnd = lpCurrent;
- fValid = FALSE;
- }
- break;
- }
- cLast = *lpCurrent++;
- }
+ // flush current buffer
+ oslFileError result = syncFile();
+ if (result != osl_File_E_None)
+ return (result);
- /* If we don't reached the end of the component the length of the component was to long
- ( See condition of while loop ) */
- if ( !lpComponentEnd )
- {
- fValid = FALSE;
- lpComponentEnd = lpCurrent;
- }
-
- /* Test wether the component specifies a device name what is not allowed */
-
- // MT: PERFORMANCE:
- // This is very expensive. A lot of calls to _tcsicmp.
- // in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp!
- // Possible optimizations
- // - Array should be const static
- // - Sorted array, use binary search
- // - More intelligent check for com1-9, lpt1-9
- // Maybe make szComponent upper case, don't search case intensitive
- // Talked to HRO: Could be removed. Shouldn't be used in OOo, and if used for something like a filename, it will lead to an error anyway.
- /*
- if ( fValid )
- {
- LPCTSTR alpDeviceNames[] =
- {
- TEXT("CON"),
- TEXT("PRN"),
- TEXT("AUX"),
- TEXT("CLOCK$"),
- TEXT("NUL"),
- TEXT("LPT1"),
- TEXT("LPT2"),
- TEXT("LPT3"),
- TEXT("LPT4"),
- TEXT("LPT5"),
- TEXT("LPT6"),
- TEXT("LPT7"),
- TEXT("LPT8"),
- TEXT("LPT9"),
- TEXT("COM1"),
- TEXT("COM2"),
- TEXT("COM3"),
- TEXT("COM4"),
- TEXT("COM5"),
- TEXT("COM6"),
- TEXT("COM7"),
- TEXT("COM8"),
- TEXT("COM9")
- };
-
- TCHAR szComponent[MAX_PATH];
- int nComponentLength;
- LPCTSTR lpDot;
- int i;
-
- // A device name with an extension is also invalid
- lpDot = _tcschr( lpComponent, '.' );
-
- if ( !lpDot || lpDot > lpComponentEnd )
- nComponentLength = lpComponentEnd - lpComponent;
- else
- nComponentLength = lpDot - lpComponent;
-
- _tcsncpy( szComponent, lpComponent, nComponentLength );
- szComponent[nComponentLength] = 0;
-
- for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ )
- {
- if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) )
+ if (nBytesToWrite >= m_bufsiz)
{
- lpComponentEnd = lpComponent;
- fValid = FALSE;
- break;
+ // buffer too small, write through to file
+ sal_uInt64 uDone = 0;
+ result = writeAt (nOffset, &(buffer[*pBytesWritten]), nBytesToWrite, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ if (uDone != nBytesToWrite)
+ return osl_File_E_IO;
+
+ nBytesToWrite -= sal::static_int_cast< DWORD >(uDone), *pBytesWritten += uDone;
+ return osl_File_E_None;
}
- }
- }
- */
-
- if ( fValid )
- {
- // Empty components are not allowed
- if ( lpComponentEnd - lpComponent < 1 )
- fValid = FALSE;
-
- // If we reached the end of the string NULL is returned
- else if ( !*lpComponentEnd )
- lpComponentEnd = NULL;
-
- }
-
- if ( lppComponentEnd )
- *lppComponentEnd = lpComponentEnd;
-
- return fValid;
- }
-
- //#####################################################
- DWORD WINAPI IsValidFilePath(rtl_uString *path, LPCTSTR *lppError, DWORD dwFlags, rtl_uString **corrected)
- {
- LPCTSTR lpszPath = reinterpret_cast< LPCTSTR >(path->buffer);
- LPCTSTR lpComponent;
- BOOL fValid = TRUE;
- DWORD dwPathType = PATHTYPE_ERROR;
-
- if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
- dwFlags |= VALIDATEPATH_ALLOW_ELLIPSE;
-
- if ( !lpszPath )
- {
- fValid = FALSE;
- lpComponent = lpszPath;
- }
- /* Test for UNC path notation */
- if ( 2 == _tcsspn( lpszPath, CHARSET_SEPARATOR ) )
- {
- /* Place the pointer behind the leading to backslashes */
-
- lpComponent = lpszPath + 2;
-
- fValid = IsValidFilePathComponent( lpComponent, &lpComponent, VALIDATEPATH_ALLOW_ELLIPSE );
-
- /* So far we have a valid servername. Now let's see if we also have a network resource */
-
- dwPathType = PATHTYPE_ABSOLUTE_UNC;
-
- if ( fValid )
- {
- if ( lpComponent && !*++lpComponent )
- lpComponent = NULL;
-
- if ( !lpComponent )
- {
- #if 0
- /* We only have a Server specification what is invalid */
-
- lpComponent = lpszPath;
- fValid = FALSE;
- #else
- dwPathType |= PATHTYPE_IS_SERVER;
- #endif
- }
- else
- {
- /* Now test the network resource */
-
- fValid = IsValidFilePathComponent( lpComponent, &lpComponent, 0 );
-
- /* If we now reached the end of the path, everything is O.K. */
-
-
- if ( fValid && (!lpComponent || lpComponent && !*++lpComponent ) )
- {
- lpComponent = NULL;
- dwPathType |= PATHTYPE_IS_VOLUME;
- }
- }
- }
- }
-
- /* Local path verification. Must start with <drive>: */
- else if ( _istalpha( lpszPath[0] ) && ':' == lpszPath[1] )
- {
- /* Place pointer behind correct drive specification */
-
- lpComponent = lpszPath + 2;
-
- if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
- lpComponent++;
- else if ( *lpComponent )
- fValid = FALSE;
-
- dwPathType = PATHTYPE_ABSOLUTE_LOCAL;
-
- /* Now we are behind the backslash or it was a simple drive without backslash */
-
- if ( fValid && !*lpComponent )
- {
- lpComponent = NULL;
- dwPathType |= PATHTYPE_IS_VOLUME;
- }
- }
-
- /* Can be a relative path */
- else if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
- {
- lpComponent = lpszPath;
-
- /* Relative path can start with a backslash */
-
- if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
- {
- lpComponent++;
- if ( !*lpComponent )
- lpComponent = NULL;
+ // update buffer (pointer)
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
}
- dwPathType = PATHTYPE_RELATIVE;
- }
+ SIZE_T const bytes = std::min(m_bufsiz - bufpos, nBytesToWrite);
+ memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes);
+ nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes;
- /* Anything else is an error */
- else
- {
- fValid = FALSE;
- lpComponent = lpszPath;
+ m_buflen = std::max(m_buflen, bufpos + bytes);
+ m_state |= STATE_MODIFIED;
}
-
- /* Now validate each component of the path */
- while ( fValid && lpComponent )
- {
- // Correct path by merging consecutive slashes:
- if (*lpComponent == '\\' && corrected != NULL) {
- sal_Int32 i = lpComponent - lpszPath;
- rtl_uString_newReplaceStrAt(corrected, path, i, 1, NULL);
- //TODO: handle out-of-memory
- lpszPath = reinterpret_cast< LPCTSTR >((*corrected)->buffer);
- lpComponent = lpszPath + i;
- }
-
- fValid = IsValidFilePathComponent( lpComponent, &lpComponent, dwFlags );
-
- if ( fValid && lpComponent )
- {
- lpComponent++;
-
- /* If the string behind the backslash is empty, we've done */
-
- if ( !*lpComponent )
- lpComponent = NULL;
- }
- }
-
- if ( fValid && _tcslen( lpszPath ) >= MAX_PATH )
- {
- fValid = FALSE;
- lpComponent = lpszPath + MAX_PATH;
- }
-
- if ( lppError )
- *lppError = lpComponent;
-
- return fValid ? dwPathType : PATHTYPE_ERROR;
+ return osl_File_E_None;
}
+}
- //#####################################################
- bool is_floppy_drive(const rtl::OUString& path);
-
- //#####################################################
- struct Component
- {
- Component() :
- begin_(0), end_(0)
- {}
-
- bool isPresent() const
- { return (static_cast<sal_Int32>(end_ - begin_) > 0); }
-
- const sal_Unicode* begin_;
- const sal_Unicode* end_;
- };
-
- //#####################################################
- struct UNCComponents
- {
- Component server_;
- Component share_;
- Component resource_;
- };
-
- //#####################################################
- const wchar_t UNC_PREFIX[] = L"\\\\";
- const wchar_t BACKSLASH = '\\';
- const wchar_t SLASH = '/';
-
- bool is_UNC_path(const sal_Unicode* path)
- { return (0 == wcsncmp(UNC_PREFIX, reinterpret_cast<LPCWSTR>(path), ELEMENTS_OF_ARRAY(UNC_PREFIX) - 1)); }
-
- //#####################################################
- bool is_UNC_path(const rtl::OUString& path)
- { return is_UNC_path(path.getStr()); }
-
- //#####################################################
- void parse_UNC_path(const sal_Unicode* path, UNCComponents* puncc)
- {
- OSL_PRECOND(is_UNC_path(path), "Precondition violated: No UNC path");
- OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) != -1, "Path must not contain slashes");
-
- const sal_Unicode* pend = path + rtl_ustr_getLength(path);
- const sal_Unicode* ppos = path + 2;
-
- puncc->server_.begin_ = ppos;
- while ((ppos < pend) && (*ppos != BACKSLASH))
- ppos++;
-
- puncc->server_.end_ = ppos;
-
- if (BACKSLASH == *ppos)
- {
- puncc->share_.begin_ = ++ppos;
- while ((ppos < pend) && (*ppos != BACKSLASH))
- ppos++;
-
- puncc->share_.end_ = ppos;
-
- if (BACKSLASH == *ppos)
- {
- puncc->resource_.begin_ = ++ppos;
- while (ppos < pend)
- ppos++;
-
- puncc->resource_.end_ = ppos;
- }
- }
-
- OSL_POSTCOND(puncc->server_.isPresent() && puncc->share_.isPresent(), \
- "Postcondition violated: Invalid UNC path detected");
- }
-
- //#####################################################
- void parse_UNC_path(const rtl::OUString& path, UNCComponents* puncc)
- { parse_UNC_path(path.getStr(), puncc); }
-
- //#####################################################
- bool is_volume_mount_point(const rtl::OUString& path)
- {
- rtl::OUString p(path);
- osl::systemPathRemoveSeparator(p);
-
- bool is_volume_root = false;
-
- if (!is_floppy_drive(p))
- {
- DWORD fattr = GetFileAttributes(reinterpret_cast<LPCTSTR>(p.getStr()));
-
- if ((INVALID_FILE_ATTRIBUTES != fattr) &&
- (FILE_ATTRIBUTE_REPARSE_POINT & fattr))
- {
- WIN32_FIND_DATA find_data;
- HANDLE h_find = FindFirstFile(reinterpret_cast<LPCTSTR>(p.getStr()), &find_data);
-
- if (IsValidHandle(h_find) &&
- (FILE_ATTRIBUTE_REPARSE_POINT & find_data.dwFileAttributes) &&
- (IO_REPARSE_TAG_MOUNT_POINT == find_data.dwReserved0))
- {
- is_volume_root = true;
- }
- if (IsValidHandle(h_find))
- FindClose(h_find);
- }
- }
- return is_volume_root;
- }
-
- //#####################################################
- // Has the given path a parent or are we already there,
- // e.g. 'c:\' or '\\server\share\'?
- bool has_path_parent(const sal_Unicode* path)
- {
- bool has_parent = false;
-
- if (is_UNC_path(path))
- {
- UNCComponents unc_comp;
- parse_UNC_path(path, &unc_comp);
- has_parent = unc_comp.resource_.isPresent();
- }
- else
- {
- has_parent = !osl::systemPathIsLogicalDrivePattern(path);
- }
- return has_parent;
- }
-
- //#####################################################
- // @see bool has_path_parent(const sal_Unicode* path)
- bool has_path_parent(const rtl::OUString& path)
- { return has_path_parent(path.getStr()); }
-
- //#####################################################
- bool path_get_parent(rtl::OUString& path)
- {
- OSL_PRECOND(path.lastIndexOf(SLASH) == -1, "Path must not have slashes");
-
- if (!has_path_parent(path))
- {
- sal_Int32 i = path.lastIndexOf(BACKSLASH);
- if (-1 < i)
- {
- path = rtl::OUString(path.getStr(), i);
- return true;
- }
- }
- return false;
- }
-
- //#############################################
- /* Cut off the last part of the given path to
- get the parent only, e.g. 'c:\dir\subdir' ->
- 'c:\dir' or '\\share\sub\dir' -> '\\share\sub'
- @return The position where the path has been cut
- off (this is the posistion of the last backslash).
- If there are no more parents 0 will be returned,
- e.g. 'c:\' or '\\Share' have no more parents */
- int path_make_parent(sal_Unicode* path)
- {
- OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) != -1, "Path must not contain slashes");
- OSL_PRECOND(has_path_parent(path), "Path must have a parent");
-
- sal_Unicode* pos_last_backslash = path + rtl_ustr_lastIndexOfChar(path, BACKSLASH);
- *pos_last_backslash = 0;
- return (pos_last_backslash - path);
- }
-
- //#####################################################
- void path_travel_to_volume_root(const rtl::OUString& system_path, rtl::OUString& volume_root)
- {
- rtl::OUString sys_path(system_path);
-
- while(!is_volume_mount_point(sys_path) && path_get_parent(sys_path))
- /**/;
-
- volume_root = sys_path;
- osl_systemPathEnsureSeparator(&volume_root.pData);
- }
-
- //#####################################################
- inline bool is_floppy_A_present()
- { return (GetLogicalDrives() & 1); }
-
- //#####################################################
- inline bool is_floppy_B_present()
- { return (GetLogicalDrives() & 2); }
-
- //#####################################################
- // determines if a volume mount point shows to a floppy
- // disk by comparing the unique volume names
- const LPWSTR FLOPPY_A = L"A:\\";
- const LPWSTR FLOPPY_B = L"B:\\";
-
- bool is_floppy_volume_mount_point(const rtl::OUString& path)
- {
- rtl::OUString p(path);
- osl_systemPathEnsureSeparator(&p.pData);
-
- TCHAR vn[51];
- if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
- {
- TCHAR vnfloppy[51];
- if (is_floppy_A_present() &&
- GetVolumeNameForVolumeMountPoint(FLOPPY_A, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
- (0 == wcscmp(vn, vnfloppy)))
- return true;
-
- if (is_floppy_B_present() &&
- GetVolumeNameForVolumeMountPoint(FLOPPY_B, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
- (0 == wcscmp(vn, vnfloppy)))
- return true;
- }
- return false;
- }
-
- //################################################
- // we must take into account that even a floppy
- // drive may be mounted to a directory so checking
- // for the drive letter alone is not sufficient
- // we must compare the unique volume name with
- // that of the available floppy disks
- LPCWSTR FLOPPY_DRV_LETTERS = TEXT("AaBb");
-
- bool is_floppy_drive(const rtl::OUString& path)
- {
- const sal_Unicode* pf = path.getStr();
- const sal_Unicode* ps = path.getStr() + 1;
- return ((wcschr(FLOPPY_DRV_LETTERS, *pf) && (L':' == *ps)) ||
- is_floppy_volume_mount_point(path));
- }
-
- //#############################################
- UINT get_volume_mount_point_drive_type(const rtl::OUString& path)
- {
- if (0 == path.getLength())
- return GetDriveType(NULL);
-
- rtl::OUString p(path);
- osl_systemPathEnsureSeparator(&p.pData);
-
- TCHAR vn[51];
- if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
- return GetDriveType(vn);
-
- return DRIVE_NO_ROOT_DIR;
- }
-
- //#############################################
- oslFileError osl_get_drive_type(const rtl::OUString& path, oslVolumeInfo* pInfo)
- {
- // GetDriveType fails on empty volume mount points
- // see Knowledge Base Q244089
- UINT drive_type;
- if (is_volume_mount_point(path))
- drive_type = get_volume_mount_point_drive_type(path);
- else
- drive_type = GetDriveType(reinterpret_cast<LPCTSTR>(path.getStr()));
-
- if (DRIVE_NO_ROOT_DIR == drive_type)
- return MapError(ERROR_INVALID_DRIVE);
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+oslFileError FileHandle_Impl::readLineAt (
+ LONGLONG nOffset,
+ sal_Sequence ** ppSequence,
+ sal_uInt64 * pBytesRead)
+{
+ oslFileError result = osl_File_E_None;
- switch (drive_type)
- {
- case DRIVE_CDROM:
- pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
- break;
- case DRIVE_REMOVABLE:
- pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
- if (is_floppy_drive(path))
- pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
- break;
- case DRIVE_FIXED:
- pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
- break;
- case DRIVE_RAMDISK:
- pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
- break;
- case DRIVE_REMOTE:
- pInfo->uAttributes |= osl_Volume_Attribute_Remote;
- break;
- case DRIVE_UNKNOWN:
- pInfo->uAttributes = 0;
- break;
- default:
- pInfo->uValidFields &= ~osl_VolumeInfo_Mask_Attributes;
- pInfo->uAttributes = 0;
- break;
- }
- return osl_File_E_None;
- }
-
- //#############################################
- inline bool is_volume_space_info_request(sal_uInt32 field_mask)
- {
- return (field_mask &
- (osl_VolumeInfo_Mask_TotalSpace |
- osl_VolumeInfo_Mask_UsedSpace |
- osl_VolumeInfo_Mask_FreeSpace));
- }
-
- //#############################################
- void get_volume_space_information(const rtl::OUString& path, oslVolumeInfo *pInfo)
+ LONGLONG bufptr = (nOffset / m_bufsiz) * m_bufsiz;
+ if (bufptr != m_bufptr)
{
- BOOL ret = GetDiskFreeSpaceEx(
- reinterpret_cast<LPCTSTR>(path.getStr()),
- (PULARGE_INTEGER)&pInfo->uFreeSpace,
- (PULARGE_INTEGER)&pInfo->uTotalSpace,
- NULL);
-
- if (ret)
- {
- pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
- pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace |
- osl_VolumeInfo_Mask_UsedSpace |
- osl_VolumeInfo_Mask_FreeSpace;
- }
- }
-
- //#############################################
- inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
- {
- return (field_mask &
- (osl_VolumeInfo_Mask_MaxNameLength |
- osl_VolumeInfo_Mask_MaxPathLength |
- osl_VolumeInfo_Mask_FileSystemName |
- osl_VolumeInfo_Mask_FileSystemCaseHandling));
- }
-
- //#############################################
- inline bool is_drivetype_request(sal_uInt32 field_mask)
- {
- return (field_mask & osl_VolumeInfo_Mask_Attributes);
- }
-
- //#############################################
- oslFileError get_filesystem_attributes(const rtl::OUString& path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
- {
- pInfo->uAttributes = 0;
-
- oslFileError osl_error = osl_File_E_None;
-
- // osl_get_drive_type must be called first because
- // this function resets osl_VolumeInfo_Mask_Attributes
- // on failure
- if (is_drivetype_request(field_mask))
- osl_error = osl_get_drive_type(path, pInfo);
-
- if ((osl_File_E_None == osl_error) && is_filesystem_attributes_request(field_mask))
- {
- WCHAR vn[MAX_PATH];
- WCHAR fsn[MAX_PATH];
- DWORD serial;
- DWORD mcl;
- DWORD flags;
-
- if (GetVolumeInformation(reinterpret_cast<LPCTSTR>(path.getStr()), vn, MAX_PATH, &serial, &mcl, &flags, fsn, MAX_PATH))
- {
- pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
- pInfo->uMaxNameLength = mcl;
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
- pInfo->uMaxPathLength = MAX_PATH;
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
- rtl_uString_newFromStr(&pInfo->ustrFileSystemName, reinterpret_cast<const sal_Unicode*>(fsn));
-
- // volumes (even NTFS) will always be considered case
- // insensitive because the Win32 API is not able to
- // deal with case sensitive volumes see M$ Knowledge Base
- // article 100625 that's why we never set the attribute
- // osl_Volume_Attribute_Case_Sensitive
-
- if (flags & FS_CASE_IS_PRESERVED)
- pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
-
- pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
- }
- }
- return osl_error;
- }
-
- //#############################################
- // Create the specified directory and call the
- // user specified callback function. On success
- // the function returns ERROR_SUCCESS else a
- // Win32 error code.
- DWORD create_dir_with_callback(
- sal_Unicode* dir_path,
- oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
- void* pData)
- {
- if (CreateDirectory(reinterpret_cast<LPCTSTR>(dir_path), NULL))
- {
- if (aDirectoryCreationCallbackFunc)
- {
- rtl::OUString url;
- FileBase::getFileURLFromSystemPath(dir_path, url);
- aDirectoryCreationCallbackFunc(pData, url.pData);
- }
- return ERROR_SUCCESS;
- }
- return GetLastError();
- }
-
- //#############################################
- DWORD create_dir_recursively_(
- sal_Unicode* dir_path,
- oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
- void* pData)
- {
- OSL_PRECOND(rtl_ustr_getLength(dir_path) > 0 && (rtl_ustr_lastIndexOfChar(dir_path, BACKSLASH) != rtl_ustr_getLength(dir_path) - 1), \
- "Path must not end with a backslash");
-
- DWORD w32_error = create_dir_with_callback(
- dir_path, aDirectoryCreationCallbackFunc, pData);
-
- if (w32_error == ERROR_SUCCESS)
- return ERROR_SUCCESS;
-
- if ((w32_error != ERROR_PATH_NOT_FOUND) || !has_path_parent(dir_path))
- return w32_error;
-
- int pos = path_make_parent(dir_path);
-
- w32_error = create_dir_recursively_(
- dir_path, aDirectoryCreationCallbackFunc, pData);
-
- if (ERROR_SUCCESS != w32_error)
- return w32_error;
-
- dir_path[pos] = BACKSLASH;
-
- return create_dir_recursively_(
- dir_path, aDirectoryCreationCallbackFunc, pData);
- }
-
- //#####################################################
- // Temp file
- //#####################################################
-
-
- //#####################################################
- 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;
- }
+ /* flush current buffer */
+ result = syncFile();
+ if (result != osl_File_E_None)
+ return (result);
- //#####################################################
- 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;
- }
+ /* update buffer (pointer) */
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
- //#####################################################
- 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 = MapError(GetLastError());
- }
-
- return osl_error;
+ m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
}
- //#####################################################
- 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);
-
- if (IsValidHandle(hFile))
- *p_handle = (oslFileHandle)hFile;
-
- return (sal_Bool)IsValidHandle(hFile);
- }
+ static int const LINE_STATE_BEGIN = 0;
+ static int const LINE_STATE_CR = 1;
+ static int const LINE_STATE_LF = 2;
- //#############################################
- 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;
- }
-
- //#####################################################
- // End Temp file
- //#####################################################
+ SIZE_T bufpos = sal::static_int_cast< SIZE_T >(nOffset - m_bufptr), curpos = bufpos, dstpos = 0;
+ int state = (bufpos >= m_buflen) ? LINE_STATE_LF : LINE_STATE_BEGIN;
-
- //#############################################
- sal_Bool _osl_decodeURL( rtl_String* strUTF8, rtl_uString** pstrDecodedURL )
+ for ( ; state != LINE_STATE_LF; )
{
- sal_Char *pBuffer;
- const sal_Char *pSrcEnd;
- const sal_Char *pSrc;
- sal_Char *pDest;
- sal_Int32 nSrcLen;
- sal_Bool bValidEncoded = sal_True; /* Assume success */
-
- /* The resulting decoded string length is shorter or equal to the source length */
-
- nSrcLen = rtl_string_getLength(strUTF8);
- pBuffer = reinterpret_cast<sal_Char*>(rtl_allocateMemory(nSrcLen + 1));
-
- pDest = pBuffer;
- pSrc = rtl_string_getStr(strUTF8);
- pSrcEnd = pSrc + nSrcLen;
-
- /* Now decode the URL what should result in an UTF8 string */
- while ( bValidEncoded && pSrc < pSrcEnd )
+ if (curpos >= m_buflen)
{
- switch ( *pSrc )
+ /* buffer examined */
+ if (0 < (curpos - bufpos))
{
- case '%':
- {
- sal_Char aToken[3];
- sal_Char aChar;
-
- pSrc++;
- aToken[0] = *pSrc++;
- aToken[1] = *pSrc++;
- aToken[2] = 0;
-
- aChar = (sal_Char)strtoul( aToken, NULL, 16 );
-
- /* The chars are path delimiters and must not be encoded */
-
- if ( 0 == aChar || '\\' == aChar || '/' == aChar || ':' == aChar )
- bValidEncoded = sal_False;
- else
- *pDest++ = aChar;
- }
- break;
- default:
- *pDest++ = *pSrc++;
- break;
+ /* flush buffer to sequence */
+ result = writeSequence_Impl (
+ ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos);
+ if (result != osl_File_E_None)
+ return (result);
+ *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
}
- }
-
- *pDest++ = 0;
-
- if ( bValidEncoded ) {
- rtl_string2UString( pstrDecodedURL, pBuffer, rtl_str_getLength(pBuffer), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
- OSL_ASSERT(*pstrDecodedURL != 0);
- }
-
- rtl_freeMemory( pBuffer );
- return bValidEncoded;
- }
-
- //#############################################
- void _osl_encodeURL( rtl_uString *strURL, rtl_String **pstrEncodedURL )
- {
- /* Encode non ascii characters within the URL */
-
- rtl_String *strUTF8 = NULL;
- sal_Char *pszEncodedURL;
- const sal_Char *pURLScan;
- sal_Char *pURLDest;
- sal_Int32 nURLScanLen;
- sal_Int32 nURLScanCount;
-
- rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
-
- pszEncodedURL = (sal_Char*) rtl_allocateMemory( (rtl_string_getLength( strUTF8 ) * 3 + 1) * sizeof(sal_Char) );
-
- pURLDest = pszEncodedURL;
- pURLScan = rtl_string_getStr( strUTF8 );
- nURLScanLen = rtl_string_getLength( strUTF8 );
- nURLScanCount = 0;
-
- while ( nURLScanCount < nURLScanLen )
- {
- sal_Char cCurrent = *pURLScan;
-
- switch ( cCurrent )
+ bufptr = nOffset / m_bufsiz * m_bufsiz;
+ if (bufptr != m_bufptr)
{
- default:
- if (!( ( cCurrent >= 'a' && cCurrent <= 'z' ) || ( cCurrent >= 'A' && cCurrent <= 'Z' ) || ( cCurrent >= '0' && cCurrent <= '9' ) ) )
- {
- sprintf( pURLDest, "%%%02X", (unsigned char)cCurrent );
- pURLDest += 3;
- break;
- }
- case '!':
- case '\'':
- case '(':
- case ')':
- case '*':
- case '-':
- case '.':
- case '_':
- case '~':
- case '$':
- case '&':
- case '+':
- case ',':
- case '=':
- case '@':
- case ':':
- case '/':
- case '\\':
- case '|':
- *pURLDest++ = cCurrent;
- break;
- case 0:
- break;
+ /* update buffer (pointer) */
+ sal_uInt64 uDone = 0;
+ result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
}
- pURLScan++;
- nURLScanCount++;
+ bufpos = sal::static_int_cast< SIZE_T >(nOffset - m_bufptr), curpos = bufpos;
+ if (bufpos >= m_buflen)
+ break;
}
-
-
- *pURLDest = 0;
-
- rtl_string_release( strUTF8 );
- rtl_string_newFromStr( pstrEncodedURL, pszEncodedURL );
- rtl_freeMemory( pszEncodedURL );
- }
-
- //#############################################
- oslFileError SAL_CALL _osl_getSystemPathFromFileURL( rtl_uString *strURL, rtl_uString **pustrPath, sal_Bool bAllowRelative )
- {
- rtl_String *strUTF8 = NULL;
- rtl_uString *strDecodedURL = NULL;
- rtl_uString *strTempPath = NULL;
- const sal_Unicode *pDecodedURL;
- sal_uInt32 nDecodedLen;
- sal_Bool bValidEncoded;
- oslFileError nError = osl_File_E_INVAL; /* Assume failure */
-
- /* If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from
- having a mixed encoded URL later */
-
- rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
-
- /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */
-
- OSL_ENSURE_FILE(
- strUTF8->length == strURL->length ||
- 0 != rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( strURL->buffer, strURL->length, "file:\\\\", 7 )
- ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL );
-
- bValidEncoded = _osl_decodeURL( strUTF8, &strDecodedURL );
-
- /* Release the encoded UTF8 string */
-
- rtl_string_release( strUTF8 );
-
-
- if ( bValidEncoded )
+ switch (state)
{
- /* Replace backslashes and pipes */
-
- rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '/', '\\' );
- rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '|', ':' );
-
- pDecodedURL = rtl_uString_getStr( strDecodedURL );
- nDecodedLen = rtl_uString_getLength( strDecodedURL );
-
- /* Must start with "file://" */
-
- if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\", 7 ) )
- {
- sal_uInt32 nSkip;
-
- if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\\\", 8 ) )
- nSkip = 8;
- else if (
- 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\localhost\\", 17 ) ||
- 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\127.0.0.1\\", 17 )
- )
- nSkip = 17;
- else
- nSkip = 5;
-
- /* Indicates local root */
- if ( nDecodedLen == nSkip )
- rtl_uString_newFromStr_WithLength( &strTempPath, reinterpret_cast<const sal_Unicode*>(WSTR_SYSTEM_ROOT_PATH), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 );
- else
- rtl_uString_newFromStr_WithLength( &strTempPath, pDecodedURL + nSkip, nDecodedLen - nSkip );
-
- if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) )
- nError = osl_File_E_None;
- }
- else if ( bAllowRelative ) /* This maybe a relative file URL */
+ case LINE_STATE_CR:
+ state = LINE_STATE_LF;
+ switch (m_buffer[curpos])
{
- rtl_uString_assign( &strTempPath, strDecodedURL );
-
- if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_RELATIVE | VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) )
- nError = osl_File_E_None;
+ case 0x0A: /* CRLF */
+ /* eat current char */
+ curpos++;
+ break;
+ default: /* single CR */
+ /* keep current char */
+ break;
}
- /*
- else
- OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL );
- */
-
- }
-
- if ( strDecodedURL )
- rtl_uString_release( strDecodedURL );
-
- if ( osl_File_E_None == nError )
- rtl_uString_assign( pustrPath, strTempPath );
-
- if ( strTempPath )
- rtl_uString_release( strTempPath );
-
- /*
- OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL );
- */
-
- return nError;
- }
-
- //#############################################
- oslFileError SAL_CALL _osl_getFileURLFromSystemPath( rtl_uString* strPath, rtl_uString** pstrURL )
- {
- oslFileError nError = osl_File_E_INVAL; /* Assume failure */
- rtl_uString *strTempURL = NULL;
- DWORD dwPathType = PATHTYPE_ERROR;
-
- if (strPath)
- dwPathType = IsValidFilePath(strPath, NULL, VALIDATEPATH_ALLOW_RELATIVE, NULL);
-
- if (dwPathType)
- {
- rtl_uString *strTempPath = NULL;
-
- /* Replace backslashes */
-
- rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' );
-
- switch ( dwPathType & PATHTYPE_MASK_TYPE )
+ break;
+ default:
+ /* determine next state */
+ switch (m_buffer[curpos])
{
- case PATHTYPE_RELATIVE:
- rtl_uString_assign( &strTempURL, strTempPath );
- nError = osl_File_E_None;
- break;
- case PATHTYPE_ABSOLUTE_UNC:
- rtl_uString_newFromAscii( &strTempURL, "file:" );
- rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
- nError = osl_File_E_None;
+ case 0x0A: /* single LF */
+ state = LINE_STATE_LF;
break;
- case PATHTYPE_ABSOLUTE_LOCAL:
- rtl_uString_newFromAscii( &strTempURL, "file:///" );
- rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
- nError = osl_File_E_None;
+ case 0x0D: /* CR */
+ state = LINE_STATE_CR;
break;
- default:
+ default: /* advance to next char */
+ curpos++;
break;
}
-
- /* Release temp path */
-
- rtl_uString_release( strTempPath );
- }
-
- if ( osl_File_E_None == nError )
- {
- rtl_String *strEncodedURL = NULL;
-
- /* Encode the URL */
-
- _osl_encodeURL( strTempURL, &strEncodedURL );
-
- /* Provide URL via unicode string */
-
- rtl_string2UString( pstrURL, rtl_string_getStr(strEncodedURL), rtl_string_getLength(strEncodedURL), RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
- OSL_ASSERT(*pstrURL != 0);
- rtl_string_release( strEncodedURL );
- }
-
- /* Release temp URL */
-
- if ( strTempURL )
- rtl_uString_release( strTempURL );
-
- /*
- OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath );
- */
-
- return nError;
- }
-
-#if OSL_DEBUG_LEVEL > 0
-
- //#####################################################
- void _osl_warnFile( const char *message, rtl_uString *ustrFile )
- {
- char szBuffer[2048];
-
- if (ustrFile)
- {
- rtl_String *strFile = NULL;
-
- rtl_uString2String( &strFile, rtl_uString_getStr( ustrFile ), rtl_uString_getLength( ustrFile ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
- snprintf( szBuffer, sizeof(szBuffer), message, strFile->buffer );
- rtl_string_release( strFile );
-
- message = szBuffer;
+ if (state != LINE_STATE_BEGIN)
+ {
+ /* store (and eat) the newline char */
+ m_buffer[curpos] = 0x0A, curpos++;
+
+ /* flush buffer to sequence */
+ result = writeSequence_Impl (
+ ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos - 1);
+ if (result != osl_File_E_None)
+ return (result);
+ *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
+ }
+ break;
}
- OSL_ENSURE( 0, message );
}
-#endif // OSL_DEBUG_LEVEL > 0
-
-} // end namespace private
-
-
-//#####################################################
-// Exported OSL API
-//#####################################################
-
-
-//#############################################
-oslFileError SAL_CALL osl_getVolumeInformation(
- rtl_uString *ustrURL, oslVolumeInfo *pInfo, sal_uInt32 uFieldMask )
-{
- if (!pInfo)
- return osl_File_E_INVAL;
-
- rtl::OUString system_path;
- oslFileError error = _osl_getSystemPathFromFileURL(ustrURL, &system_path.pData, sal_False);
-
- if (osl_File_E_None != error)
- return error;
-
- rtl::OUString volume_root;
- path_travel_to_volume_root(system_path, volume_root);
-
- pInfo->uValidFields = 0;
-
- if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
- return error;
-
- if (is_volume_space_info_request(uFieldMask))
- get_volume_space_information(volume_root, pInfo);
-
- if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
- {
- pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
- osl_getFileURLFromSystemPath(volume_root.pData, (rtl_uString**)&pInfo->pDeviceHandle);
- }
-
+ result = writeSequence_Impl (ppSequence, &dstpos, 0, 0);
+ if (result != osl_File_E_None)
+ return (result);
+ if (0 < dstpos)
+ return osl_File_E_None;
+ if (bufpos >= m_buflen)
+ return osl_File_E_AGAIN;
return osl_File_E_None;
}
-
-//#############################################
-oslFileError SAL_CALL osl_createDirectoryPath(
- rtl_uString* aDirectoryUrl,
- oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
- void* pData)
-{
- if (aDirectoryUrl == NULL)
- return osl_File_E_INVAL;
-
- rtl::OUString sys_path;
- oslFileError osl_error =
- _osl_getSystemPathFromFileURL(aDirectoryUrl, &sys_path.pData, sal_False);
-
- if (osl_error != osl_File_E_None)
- return osl_error;
-
- systemPathRemoveSeparator(sys_path);
-
- // const_cast because sys_path is a local copy
- // which we want to modify inplace instead of
- // coyp it into another buffer on the heap again
- return MapError(create_dir_recursively_(
- sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData));
-}
-
-//#############################################
-oslFileError SAL_CALL osl_createTempFile(
- rtl_uString* pustrDirectoryURL,
- oslFileHandle* pHandle,
- rtl_uString** ppustrTempFileURL)
+oslFileError FileHandle_Impl::writeSequence_Impl (
+ sal_Sequence ** ppSequence,
+ SIZE_T * pnOffset,
+ const void * pBuffer,
+ SIZE_T nBytes)
{
- 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 */
- STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH));
-
- if (tmp_name)
+ sal_Int32 nElements = *pnOffset + nBytes;
+ if (!*ppSequence)
{
- osl_createTempFile_impl_(
- base_directory,
- tmp_name,
- b_delete_on_close,
- pHandle,
- ppustrTempFileURL);
+ /* construct sequence */
+ rtl_byte_sequence_constructNoDefault(ppSequence, nElements);
}
- else // stack alloc failed
+ else if (nElements != (*ppSequence)->nElements)
{
- osl_error = osl_File_E_NOMEM;
+ /* resize sequence */
+ rtl_byte_sequence_realloc(ppSequence, nElements);
}
-
- if (base_directory)
- rtl_uString_release(base_directory);
-
- return osl_error;
-}
-
-//#############################################
-oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir)
-{
- WCHAR szBuffer[MAX_PATH];
- LPWSTR lpBuffer = szBuffer;
- DWORD nBufferLength = ELEMENTS_OF_ARRAY(szBuffer) - 1;
-
- DWORD nLength;
- oslFileError error;
-
- do
- {
- nLength = GetTempPathW( ELEMENTS_OF_ARRAY(szBuffer), lpBuffer );
- if ( nLength > nBufferLength )
- {
- nLength++;
- lpBuffer = reinterpret_cast<WCHAR*>(alloca( sizeof(WCHAR) * nLength ));
- nBufferLength = nLength - 1;
- }
- } while ( nLength > nBufferLength );
-
- if ( nLength )
+ if (*ppSequence != 0)
{
- 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 );
+ /* fill sequence */
+ memcpy(&((*ppSequence)->elements[*pnOffset]), pBuffer, nBytes), *pnOffset += nBytes;
}
- else
- error = MapError( GetLastError() );
-
- return error;
+ return (*ppSequence != 0) ? osl_File_E_None : osl_File_E_NOMEM;
}
+oslFileError FileHandle_Impl::syncFile()
+{
+ oslFileError result = osl_File_E_None;
+ if (m_state & STATE_MODIFIED)
+ {
+ sal_uInt64 uDone = 0;
+ result = writeAt (m_bufptr, m_buffer, m_buflen, &uDone);
+ if (result != osl_File_E_None)
+ return (result);
+ if (uDone != m_buflen)
+ return osl_File_E_IO;
+ m_state &= ~STATE_MODIFIED;
+ }
+ return (result);
+}
+
//##################################################################
-// File handling functions
+// File I/O functions
//##################################################################
-
-
-//#############################################
-oslFileError SAL_CALL osl_openFile(
- rtl_uString *strPath, oslFileHandle *pHandle, sal_uInt32 uFlags )
+
+extern "C" oslFileHandle
+SAL_CALL osl_createFileHandleFromOSHandle (
+ HANDLE hFile,
+ sal_uInt32 uFlags)
{
- rtl_uString *strSysPath = NULL;
- oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
+ if ( !IsValidHandle(hFile) )
+ return 0; // EINVAL
- if ( osl_File_E_None == error )
+ FileHandle_Impl * pImpl = new FileHandle_Impl(hFile);
+ if (pImpl == 0)
{
- DWORD dwAccess = 0, dwShare = FILE_SHARE_READ, dwCreation = 0, dwAttributes = 0;
- HANDLE hFile;
-
- if ( uFlags & osl_File_OpenFlag_Read )
- dwAccess |= GENERIC_READ;
-
- if ( uFlags & osl_File_OpenFlag_Write )
- dwAccess |= GENERIC_WRITE;
- else
- dwShare |= FILE_SHARE_WRITE;
-
- if ( uFlags & osl_File_OpenFlag_NoLock )
- dwShare |= FILE_SHARE_WRITE;
-
- if ( uFlags & osl_File_OpenFlag_Create )
- dwCreation |= CREATE_NEW;
- else
- dwCreation |= OPEN_EXISTING;
-
- hFile = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), dwAccess, dwShare, NULL, dwCreation, dwAttributes, NULL );
-
- *pHandle = osl_createFileHandleFromOSHandle( hFile );
-
- if ( !IsValidHandle( hFile ) )
- error = MapError( GetLastError() );
-
- rtl_uString_release( strSysPath );
+ // cleanup and fail
+ (void) ::CloseHandle(hFile);
+ return 0; // ENOMEM
}
- return error;
-}
-
-//#############################################
-oslFileError SAL_CALL osl_syncFile(oslFileHandle Handle)
-{
- if (!IsValidHandle((HANDLE)Handle))
- return osl_File_E_INVAL;
-
- if (!FlushFileBuffers((HANDLE)Handle))
- return MapError(GetLastError());
-
- return osl_File_E_None;
-}
+ /* check for regular file */
+ if (FILE_TYPE_DISK == GetFileType(hFile))
+ {
+ /* mark seekable */
+ pImpl->m_state |= FileHandle_Impl::STATE_SEEKABLE;
-//#############################################
-oslFileError SAL_CALL osl_closeFile(oslFileHandle Handle)
-{
- oslFileError error;
- HANDLE hFile = (HANDLE)Handle;
+ /* init current size */
+ LARGE_INTEGER uSize = { 0, 0 };
+ (void) ::GetFileSizeEx(hFile, &uSize);
+ pImpl->m_size = (sal::static_int_cast<sal_uInt64>(uSize.HighPart) << 32) + uSize.LowPart;
+ }
- if ( IsValidHandle(hFile) )
- error = CloseHandle( hFile ) ? osl_File_E_None : MapError( GetLastError() );
- else
- error = osl_File_E_INVAL;
+ if (!(uFlags & osl_File_OpenFlag_Read))
+ pImpl->m_state &= ~FileHandle_Impl::STATE_READABLE;
+ if (!(uFlags & osl_File_OpenFlag_Write))
+ pImpl->m_state &= ~FileHandle_Impl::STATE_WRITEABLE;
- return error;
+ OSL_POSTCOND(
+ (uFlags & osl_File_OpenFlag_Read) || (uFlags & osl_File_OpenFlag_Write),
+ "osl_createFileHandleFromOSHandle(): missing read/write access flags");
+ return (oslFileHandle)(pImpl);
}
//#############################################
-oslFileError SAL_CALL osl_isEndOfFile(oslFileHandle Handle, sal_Bool *pIsEOF)
+oslFileError
+SAL_CALL osl_openFile(
+ rtl_uString * strPath,
+ oslFileHandle * pHandle,
+ sal_uInt32 uFlags )
{
- oslFileError error = osl_File_E_INVAL;
- HANDLE hFile = (HANDLE)Handle;
-
- if ( IsValidHandle(hFile) )
- {
- LONG lDistanceToMove, lDistanceToMoveHigh;
- sal_uInt64 nCurPos;
-
- /* Return value INVALID_SET_FILE_POINTER is no error indication and LastError could
- be set from previous IO call */
-
- SetLastError( NOERROR );
+ rtl_uString * strSysPath = 0;
+ oslFileError result = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
+ if (result != osl_File_E_None)
+ return (result);
- lDistanceToMoveHigh = 0;
- lDistanceToMove = SetFilePointer( hFile, 0, &lDistanceToMoveHigh, FILE_CURRENT );
+ DWORD dwAccess = GENERIC_READ, dwShare = FILE_SHARE_READ, dwCreation = 0, dwAttributes = 0;
- error = MapError( GetLastError() );
-
- if ( osl_File_E_None == error )
- {
- nCurPos = (sal_uInt64)lDistanceToMove + ((sal_uInt64)lDistanceToMoveHigh << 32);
+ if ( uFlags & osl_File_OpenFlag_Write )
+ dwAccess |= GENERIC_WRITE;
+ else
+ dwShare |= FILE_SHARE_WRITE;
- lDistanceToMoveHigh = 0;
- lDistanceToMove = SetFilePointer( hFile, 0, &lDistanceToMoveHigh, FILE_END );
+ if ( uFlags & osl_File_OpenFlag_NoLock )
+ dwShare |= FILE_SHARE_WRITE;
- error = MapError( GetLastError() );
+ if ( uFlags & osl_File_OpenFlag_Create )
+ dwCreation |= CREATE_NEW;
+ else
+ dwCreation |= OPEN_EXISTING;
- if ( osl_File_E_None == error )
- {
- sal_uInt64 nEndPos = (sal_uInt64)lDistanceToMove + ((sal_uInt64)lDistanceToMoveHigh << 32);
+ HANDLE hFile = CreateFileW(
+ reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )),
+ dwAccess, dwShare, NULL, dwCreation, dwAttributes, NULL );
- *pIsEOF = (sal_Bool)(nEndPos == nCurPos);
+ // @@@ ERROR HANDLING @@@
+ if ( !IsValidHandle( hFile ) )
+ result = oslTranslateFileError( GetLastError() );
- lDistanceToMoveHigh = (LONG)(nCurPos >> 32);
- SetFilePointer( hFile, (LONG)(nCurPos & 0xFFFFFFFF), &lDistanceToMoveHigh, FILE_BEGIN );
+ *pHandle = osl_createFileHandleFromOSHandle (hFile, uFlags | osl_File_OpenFlag_Read);
- error = MapError( GetLastError() );
- }
- }
- }
- return error;
+ rtl_uString_release( strSysPath );
+ return (result);
}
//#############################################
-oslFileError SAL_CALL osl_setFilePos(oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos)
+oslFileError
+SAL_CALL osl_syncFile(oslFileHandle Handle)
{
- HANDLE hFile = (HANDLE)Handle;
- if (!IsValidHandle(hFile))
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
return osl_File_E_INVAL;
- DWORD dwMoveMethod = 0;
- switch ( uHow )
- {
- case osl_Pos_Current:
- dwMoveMethod = FILE_CURRENT;
- break;
- case osl_Pos_End:
- dwMoveMethod = FILE_END;
- break;
- case osl_Pos_Absolut:
- default:
- dwMoveMethod = FILE_BEGIN;
- break;
- }
+ oslFileError result = pImpl->syncFile();
+ if (result != osl_File_E_None)
+ return result;
- LONG nOffsetLo = sal::static_int_cast<LONG>(uPos & 0xFFFFFFFF);
- LONG nOffsetHi = sal::static_int_cast<LONG>(uPos >> 32);
-
- SetLastError(0);
- DWORD dwPosLo = SetFilePointer( hFile, nOffsetLo, &nOffsetHi, dwMoveMethod );
- if (INVALID_SET_FILE_POINTER == dwPosLo)
- {
- DWORD dwError = GetLastError();
- if (NO_ERROR != dwError)
- return MapError( dwError );
- }
+ if (!FlushFileBuffers(pImpl->m_hFile))
+ return oslTranslateFileError(GetLastError());
+
return osl_File_E_None;
}
//#############################################
-oslFileError SAL_CALL osl_getFilePos(oslFileHandle Handle, sal_uInt64 *pPos)
-{
- oslFileError error;
- HANDLE hFile = (HANDLE)Handle;
-
- if ( IsValidHandle(hFile) )
- {
- LONG lDistanceToMove, lDistanceToMoveHigh;
-
- /* Return value INVALID_SET_FILE_POINTER is no error indication and LastError could
- be set from previous IO call */
-
- SetLastError( NOERROR );
-
- lDistanceToMoveHigh = 0;
- lDistanceToMove = SetFilePointer( hFile, 0, &lDistanceToMoveHigh, FILE_CURRENT );
-
- error = MapError( GetLastError() );
-
- if ( osl_File_E_None == error )
- *pPos = (sal_uInt64)lDistanceToMove + ((sal_uInt64)lDistanceToMoveHigh << 32);
- }
- else
- error = osl_File_E_INVAL;
-
- return error;
-}
-
-//#############################################
-oslFileError SAL_CALL osl_getFileSize(oslFileHandle Handle, sal_uInt64 *pSize)
+oslFileError
+SAL_CALL osl_closeFile(oslFileHandle Handle)
{
- HANDLE hFile = (HANDLE)Handle;
- if ( !IsValidHandle(hFile) )
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
return osl_File_E_INVAL;
- DWORD nSize = GetFileSize(hFile, NULL);
- if (nSize == INVALID_FILE_SIZE)
+ oslFileError result = pImpl->syncFile();
+ if (result != osl_File_E_None)
{
- DWORD nError = GetLastError();
- if (nError != NO_ERROR)
- return MapError(nError);
+ /* ignore double failure */
+ (void)::CloseHandle(pImpl->m_hFile);
}
-
- *pSize = (sal_uInt64)(nSize);
- return osl_File_E_None;
-}
-
-oslFileError SAL_CALL osl_setFileSize(oslFileHandle Handle, sal_uInt64 uSize)
-{
- oslFileError error = osl_setFilePos( Handle, osl_Pos_Absolut, uSize );
- if ( osl_File_E_None == error )
+ else if (!::CloseHandle(pImpl->m_hFile))
{
- if ( !SetEndOfFile( (HANDLE)Handle ) )
- error = MapError( osl_File_E_None );
+ /* translate error code */
+ result = oslTranslateFileError( GetLastError() );
}
- return error;
+ delete pImpl;
+ return (result);
}
//#############################################
-oslFileError SAL_CALL osl_mapFile(
+oslFileError
+SAL_CALL osl_mapFile(
oslFileHandle Handle,
void** ppAddr,
sal_uInt64 uLength,
@@ -2710,8 +768,8 @@ oslFileError SAL_CALL osl_mapFile(
}
};
- HANDLE hFile = (HANDLE)(Handle);
- if (!IsValidHandle(hFile) || (0 == ppAddr))
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == ppAddr))
return osl_File_E_INVAL;
*ppAddr = 0;
@@ -2727,16 +785,16 @@ oslFileError SAL_CALL osl_mapFile(
if (VER_PLATFORM_WIN32_NT != osinfo.dwPlatformId)
return osl_File_E_NOSYS; // Unsupported
- FileMapping aMap( ::CreateFileMapping (hFile, NULL, SEC_COMMIT | PAGE_READONLY, 0, 0, NULL) );
+ FileMapping aMap( ::CreateFileMapping (pImpl->m_hFile, NULL, SEC_COMMIT | PAGE_READONLY, 0, 0, NULL) );
if (!IsValidHandle(aMap.m_handle))
- return MapError( GetLastError() );
+ return oslTranslateFileError( GetLastError() );
DWORD const dwOffsetHi = sal::static_int_cast<DWORD>(uOffset >> 32);
DWORD const dwOffsetLo = sal::static_int_cast<DWORD>(uOffset & 0xFFFFFFFF);
*ppAddr = ::MapViewOfFile( aMap.m_handle, FILE_MAP_READ, dwOffsetHi, dwOffsetLo, nLength );
if (0 == *ppAddr)
- return MapError( GetLastError() );
+ return oslTranslateFileError( GetLastError() );
if (uFlags & osl_File_MapFlag_RandomAccess)
{
@@ -2770,977 +828,320 @@ oslFileError SAL_CALL osl_mapFile(
}
//#############################################
-oslFileError SAL_CALL osl_unmapFile(void* pAddr, sal_uInt64 /* uLength */)
+oslFileError
+SAL_CALL osl_unmapFile(void* pAddr, sal_uInt64 /* uLength */)
{
if (0 == pAddr)
return osl_File_E_INVAL;
if (!::UnmapViewOfFile (pAddr))
- return MapError( GetLastError() );
+ return oslTranslateFileError( GetLastError() );
return osl_File_E_None;
}
//#############################################
-oslFileError SAL_CALL osl_readFile(
- oslFileHandle Handle,
- void *pBuffer,
- sal_uInt64 uBytesRequested,
- sal_uInt64 *pBytesRead )
+oslFileError
+SAL_CALL osl_readLine(
+ oslFileHandle Handle,
+ sal_Sequence ** ppSequence)
{
- oslFileError error;
- HANDLE hFile = (HANDLE)Handle;
-
- if ( IsValidHandle(hFile) )
- {
- DWORD dwBytesToRead = (DWORD)uBytesRequested;
- DWORD dwBytesRead;
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == ppSequence))
+ return osl_File_E_INVAL;
+ sal_uInt64 uBytesRead = 0;
+
+ // read at current filepos; filepos += uBytesRead;
+ oslFileError result = pImpl->readLineAt (
+ pImpl->m_filepos, ppSequence, &uBytesRead);
+ if (result == osl_File_E_None)
+ pImpl->m_filepos += uBytesRead;
+ return (result);
+}
- if ( ReadFile( hFile, pBuffer, dwBytesToRead, &dwBytesRead, NULL ) )
- {
- *pBytesRead = (sal_uInt64)dwBytesRead;
- error = osl_File_E_None;
- }
- else
- error = MapError( GetLastError() );
- }
- else
- error = osl_File_E_INVAL;
+//#############################################
+oslFileError
+SAL_CALL osl_readFile(
+ oslFileHandle Handle,
+ void * pBuffer,
+ sal_uInt64 uBytesRequested,
+ sal_uInt64 * pBytesRead)
+{
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesRead))
+ return osl_File_E_INVAL;
- return error;
+ // read at current filepos; filepos += *pBytesRead;
+ oslFileError result = pImpl->readFileAt (
+ pImpl->m_filepos, pBuffer, uBytesRequested, pBytesRead);
+ if (result == osl_File_E_None)
+ pImpl->m_filepos += *pBytesRead;
+ return (result);
}
//#############################################
-oslFileError SAL_CALL osl_writeFile(
+oslFileError
+SAL_CALL osl_writeFile(
oslFileHandle Handle,
- const void *pBuffer,
- sal_uInt64 uBytesToWrite,
- sal_uInt64 *pBytesWritten )
+ const void * pBuffer,
+ sal_uInt64 uBytesToWrite,
+ sal_uInt64 * pBytesWritten )
{
- oslFileError error;
- HANDLE hFile = (HANDLE)Handle;
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ( IsValidHandle(hFile) )
- {
- DWORD dwBytesToWrite = (DWORD)uBytesToWrite;
- DWORD dwBytesWritten;
-
- if ( WriteFile( hFile, pBuffer, dwBytesToWrite, &dwBytesWritten, NULL ) )
- {
- *pBytesWritten = (sal_uInt64)dwBytesWritten;
- error = osl_File_E_None;
- }
- else
- error = MapError( GetLastError() );
- }
- else
- error = osl_File_E_INVAL;
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesWritten))
+ return osl_File_E_INVAL;
- return error;
+ // write at current filepos; filepos += *pBytesWritten;
+ oslFileError result = pImpl->writeFileAt (
+ pImpl->m_filepos, pBuffer, uBytesToWrite, pBytesWritten);
+ if (result == osl_File_E_None)
+ pImpl->m_filepos += *pBytesWritten;
+ return (result);
}
//#############################################
-oslFileError SAL_CALL osl_readFileAt(
+oslFileError
+SAL_CALL osl_readFileAt(
oslFileHandle Handle,
sal_uInt64 uOffset,
void* pBuffer,
sal_uInt64 uBytesRequested,
sal_uInt64* pBytesRead)
{
- HANDLE hFile = (HANDLE)(Handle);
- if (!IsValidHandle(hFile) || (0 == pBuffer))
- return osl_File_E_INVAL;
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max();
- if (g_limit_dword < uBytesRequested)
- return osl_File_E_OVERFLOW;
- DWORD const dwBytes = sal::static_int_cast< DWORD >(uBytesRequested);
-
- if (0 == pBytesRead)
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesRead))
return osl_File_E_INVAL;
- *pBytesRead = 0;
-
- oslFileError error = osl_setFilePos(Handle, osl_Pos_Absolut, uOffset);
- if (osl_File_E_None != error)
- return error;
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
- DWORD dwDone = 0;
- if (!::ReadFile(hFile, pBuffer, dwBytes, &dwDone, NULL))
- return MapError( GetLastError() );
+ static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
+ if (g_limit_longlong < uOffset)
+ return osl_File_E_OVERFLOW;
+ LONGLONG const nOffset = sal::static_int_cast< LONGLONG >(uOffset);
- *pBytesRead = dwDone;
- return osl_File_E_None;
+ // read at specified fileptr
+ return pImpl->readFileAt (nOffset, pBuffer, uBytesRequested, pBytesRead);
}
//#############################################
-oslFileError SAL_CALL osl_writeFileAt(
+oslFileError
+SAL_CALL osl_writeFileAt(
oslFileHandle Handle,
sal_uInt64 uOffset,
const void* pBuffer,
sal_uInt64 uBytesToWrite,
sal_uInt64* pBytesWritten)
{
- HANDLE hFile = (HANDLE)(Handle);
- if (!IsValidHandle(hFile) || (0 == pBuffer))
- return osl_File_E_INVAL;
-
- static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max();
- if (g_limit_dword < uBytesToWrite)
- return osl_File_E_OVERFLOW;
- DWORD const dwBytes = sal::static_int_cast< DWORD >(uBytesToWrite);
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- if (0 == pBytesWritten)
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesWritten))
return osl_File_E_INVAL;
- *pBytesWritten = 0;
-
- oslFileError error = osl_setFilePos(Handle, osl_Pos_Absolut, uOffset);
- if (osl_File_E_None != error)
- return error;
-
- DWORD dwDone = 0;
- if (!::WriteFile(hFile, pBuffer, dwBytes, &dwDone, NULL))
- return MapError( GetLastError() );
-
- *pBytesWritten = dwDone;
- return osl_File_E_None;
-}
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
+ return osl_File_E_SPIPE;
-//#############################################
-oslFileError SAL_CALL osl_removeFile( rtl_uString* strPath )
-{
- rtl_uString *strSysPath = NULL;
- oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
-
- if ( osl_File_E_None == error )
- {
- if ( DeleteFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) )
- error = osl_File_E_None;
- else
- error = MapError( GetLastError() );
+ static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
+ if (g_limit_longlong < uOffset)
+ return osl_File_E_OVERFLOW;
+ LONGLONG const nOffset = sal::static_int_cast< LONGLONG >(uOffset);
- rtl_uString_release( strSysPath );
- }
- return error;
+ // write at specified fileptr
+ return pImpl->writeFileAt (nOffset, pBuffer, uBytesToWrite, pBytesWritten);
}
//#############################################
-#define osl_File_CopyRecursive 0x0001
-#define osl_File_CopyOverwrite 0x0002
-
-oslFileError SAL_CALL osl_copyFile( rtl_uString* strPath, rtl_uString *strDestPath )
+oslFileError
+SAL_CALL osl_isEndOfFile (oslFileHandle Handle, sal_Bool *pIsEOF)
{
- rtl_uString *strSysPath = NULL, *strSysDestPath = NULL;
- oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
-
- if ( osl_File_E_None == error )
- error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False );
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ( osl_File_E_None == error )
- {
- if ( CopyFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )), reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath )), FALSE ) )
- error = osl_File_E_None;
- else
- error = MapError( GetLastError() );
- }
-
- if ( strSysPath )
- rtl_uString_release( strSysPath );
- if ( strSysDestPath )
- rtl_uString_release( strSysDestPath );
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pIsEOF))
+ return osl_File_E_INVAL;
- return error;
+ *pIsEOF = (pImpl->getPos() == pImpl->getSize());
+ return osl_File_E_None;
}
//#############################################
-oslFileError SAL_CALL osl_moveFile( rtl_uString* strPath, rtl_uString *strDestPath )
+oslFileError
+SAL_CALL osl_getFilePos(oslFileHandle Handle, sal_uInt64 *pPos)
{
- rtl_uString *strSysPath = NULL, *strSysDestPath = NULL;
- oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
-
- if ( osl_File_E_None == error )
- error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False );
-
- if ( osl_File_E_None == error )
- {
- if ( MoveFileEx( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )), reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING ) )
- error = osl_File_E_None;
- else
- error = MapError( GetLastError() );
- }
-
- if ( strSysPath )
- rtl_uString_release( strSysPath );
- if ( strSysDestPath )
- rtl_uString_release( strSysDestPath );
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pPos))
+ return osl_File_E_INVAL;
- return error;
+ *pPos = pImpl->getPos();
+ return osl_File_E_None;
}
//#############################################
-oslFileError SAL_CALL osl_setFileAttributes(
- rtl_uString *ustrFileURL,
- sal_uInt64 uAttributes )
+oslFileError
+SAL_CALL osl_setFilePos(oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffset)
{
- oslFileError error;
- rtl_uString *ustrSysPath = NULL;
- DWORD dwFileAttributes;
- BOOL fSuccess;
-
- // Converts the normalized path into a systempath
- error = _osl_getSystemPathFromFileURL( ustrFileURL, &ustrSysPath, sal_False );
-
- if ( osl_File_E_None != error )
- return error;
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
+ return osl_File_E_INVAL;
- dwFileAttributes = GetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)) );
+ static sal_Int64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
+ if (g_limit_longlong < uOffset)
+ return osl_File_E_OVERFLOW;
+ LONGLONG nPos = 0, nOffset = sal::static_int_cast< LONGLONG >(uOffset);
- if ( (DWORD)-1 != dwFileAttributes )
+ switch (uHow)
{
- dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN);
+ case osl_Pos_Absolut:
+ if (0 > nOffset)
+ return osl_File_E_INVAL;
+ break;
- if ( uAttributes & osl_File_Attribute_ReadOnly )
- dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
+ case osl_Pos_Current:
+ nPos = sal::static_int_cast< LONGLONG >(pImpl->getPos());
+ if ((0 > nOffset) && (-1*nOffset > nPos))
+ return osl_File_E_INVAL;
+ if (g_limit_longlong < nPos + nOffset)
+ return osl_File_E_OVERFLOW;
+ break;
- if ( uAttributes & osl_File_Attribute_Hidden )
- dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
+ case osl_Pos_End:
+ nPos = sal::static_int_cast< LONGLONG >(pImpl->getSize());
+ if ((0 > nOffset) && (-1*nOffset > nPos))
+ return osl_File_E_INVAL;
+ if (g_limit_longlong < nPos + nOffset)
+ return osl_File_E_OVERFLOW;
+ break;
- fSuccess = SetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)), dwFileAttributes );
+ default:
+ return osl_File_E_INVAL;
}
- else
- fSuccess = FALSE;
-
- if ( !fSuccess )
- error = MapError( GetLastError() );
- rtl_uString_release( ustrSysPath );
-
- return error;
+ return pImpl->setPos (nPos + nOffset);
}
-//#####################################################
-oslFileError SAL_CALL osl_setFileTime(
- rtl_uString *filePath,
- const TimeValue *aCreationTime,
- const TimeValue *aLastAccessTime,
- const TimeValue *aLastWriteTime)
+//#############################################
+oslFileError
+SAL_CALL osl_getFileSize (oslFileHandle Handle, sal_uInt64 *pSize)
{
- oslFileError error;
- rtl_uString *sysPath=NULL;
- FILETIME *lpCreationTime=NULL;
- FILETIME *lpLastAccessTime=NULL;
- FILETIME *lpLastWriteTime=NULL;
- FILETIME ftCreationTime;
- FILETIME ftLastAccessTime;
- FILETIME ftLastWriteTime;
- HANDLE hFile;
- BOOL fSuccess;
-
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- error=_osl_getSystemPathFromFileURL(filePath, &sysPath, sal_False);
-
- if (error==osl_File_E_INVAL)
- return error;
-
- hFile=CreateFileW(reinterpret_cast<LPCWSTR>(rtl_uString_getStr(sysPath)), GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- rtl_uString_release(sysPath);
-
- if (hFile==INVALID_HANDLE_VALUE)
- return osl_File_E_NOENT;
-
- if (TimeValueToFileTime(aCreationTime, &ftCreationTime))
- lpCreationTime=&ftCreationTime;
-
- if (TimeValueToFileTime(aLastAccessTime, &ftLastAccessTime))
- lpLastAccessTime=&ftLastAccessTime;
-
- if (TimeValueToFileTime(aLastWriteTime, &ftLastWriteTime))
- lpLastWriteTime=&ftLastWriteTime;
-
- fSuccess=SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
-
- CloseHandle(hFile);
-
- if (!fSuccess)
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pSize))
return osl_File_E_INVAL;
- else
- return osl_File_E_None;
+
+ *pSize = pImpl->getSize();
+ return osl_File_E_None;
}
-//#####################################################
-oslFileError SAL_CALL osl_getFileStatus(
- oslDirectoryItem Item,
- oslFileStatus *pStatus,
- sal_uInt32 uFieldMask )
+//#############################################
+oslFileError
+SAL_CALL osl_setFileSize (oslFileHandle Handle, sal_uInt64 uSize)
{
- DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
-
- if ( !pItemImpl )
- return osl_File_E_INVAL;
-
- switch ( pItemImpl->uType )
- {
- case DIRECTORYITEM_DRIVE:
- return osl_getDriveInfo( Item, pStatus, uFieldMask );
- case DIRECTORYITEM_SERVER:
- return osl_getServerInfo( Item, pStatus, uFieldMask );
- default:
- break;
- }
+ FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ( uFieldMask & osl_FileStatus_Mask_Validate )
- {
- HANDLE hFind = FindFirstFile( pItemImpl->szFullPath, &pItemImpl->FindData );
-
- if ( hFind != INVALID_HANDLE_VALUE )
- FindClose( hFind );
- else
- return MapError( GetLastError() );
-
- uFieldMask &= ~ osl_FileStatus_Mask_Validate;
- }
-
- /* If no fields to retrieve left ignore pStatus */
- if ( !uFieldMask )
- return osl_File_E_None;
-
- /* Otherwise, this must be a valid pointer */
- if ( !pStatus )
- return osl_File_E_INVAL;
-
- if ( pStatus->uStructSize != sizeof(oslFileStatus) )
+ if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
return osl_File_E_INVAL;
+ if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
+ return osl_File_E_BADF;
- pStatus->uValidFields = 0;
-
- /* File time stamps */
-
- if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime) &&
- FileTimeToTimeValue( &pItemImpl->FindData.ftLastWriteTime, &pStatus->aModifyTime ) )
- pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;
-
- if ( (uFieldMask & osl_FileStatus_Mask_AccessTime) &&
- FileTimeToTimeValue( &pItemImpl->FindData.ftLastAccessTime, &pStatus->aAccessTime ) )
- pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;
-
- if ( (uFieldMask & osl_FileStatus_Mask_CreationTime) &&
- FileTimeToTimeValue( &pItemImpl->FindData.ftCreationTime, &pStatus->aCreationTime ) )
- pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;
-
- /* Most of the fields are already set, regardless of requiered fields */
-
- rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(pItemImpl->FindData.cFileName) );
- pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
-
- if ((FILE_ATTRIBUTE_REPARSE_POINT & pItemImpl->FindData.dwFileAttributes) &&
- (IO_REPARSE_TAG_MOUNT_POINT == pItemImpl->FindData.dwReserved0))
- pStatus->eType = osl_File_Type_Volume;
- else if (pItemImpl->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- pStatus->eType = osl_File_Type_Directory;
- else
- pStatus->eType = osl_File_Type_Regular;
-
- pStatus->uValidFields |= osl_FileStatus_Mask_Type;
-
- pStatus->uAttributes = pItemImpl->FindData.dwFileAttributes;
- pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;
-
- pStatus->uFileSize = (sal_uInt64)pItemImpl->FindData.nFileSizeLow + ((sal_uInt64)pItemImpl->FindData.nFileSizeHigh << 32);
- pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;
-
- if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
- {
- rtl_uString *ustrFullPath = NULL;
-
- rtl_uString_newFromStr( &ustrFullPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) );
- osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrLinkTargetURL );
- rtl_uString_release( ustrFullPath );
+ static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
+ if (g_limit_longlong < uSize)
+ return osl_File_E_OVERFLOW;
- pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
- }
+ oslFileError result = pImpl->syncFile();
+ if (result != osl_File_E_None)
+ return (result);
- if ( uFieldMask & osl_FileStatus_Mask_FileURL )
- {
- rtl_uString *ustrFullPath = NULL;
+ LARGE_INTEGER nDstPos; nDstPos.QuadPart = sal::static_int_cast< LONGLONG >(uSize);
+ if (!::SetFilePointerEx(pImpl->m_hFile, nDstPos, 0, FILE_BEGIN))
+ return oslTranslateFileError( GetLastError() );
+ if (!::SetEndOfFile(pImpl->m_hFile))
+ return oslTranslateFileError( GetLastError() );
+ pImpl->m_size = uSize;
- if ( !pItemImpl->bFullPathNormalized )
- {
- GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );
- pItemImpl->bFullPathNormalized = TRUE;
- }
- rtl_uString_newFromStr( &ustrFullPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) );
- osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL );
- rtl_uString_release( ustrFullPath );
- pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
- }
+ nDstPos.QuadPart = pImpl->m_offset;
+ if (!::SetFilePointerEx(pImpl->m_hFile, nDstPos, 0, FILE_BEGIN))
+ return oslTranslateFileError( GetLastError() );
return osl_File_E_None;
}
//##################################################################
-// directory handling functions
+// File handling functions
//##################################################################
-
-
-//#####################################################
-oslFileError SAL_CALL osl_createDirectory(rtl_uString* strPath)
+
+//#############################################
+oslFileError SAL_CALL osl_removeFile( rtl_uString* strPath )
{
rtl_uString *strSysPath = NULL;
oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
if ( osl_File_E_None == error )
{
- if ( CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), NULL ) )
+ if ( DeleteFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) )
error = osl_File_E_None;
-/*@@@ToDo
- The else case is a hack because the ucb or the webtop had some
- problems with the error code that CreateDirectory returns in
- case the path is only a logical drive, should be removed!
-*/
else
- {
- const sal_Unicode *pBuffer = rtl_uString_getStr( strSysPath );
- sal_Int32 nLen = rtl_uString_getLength( strSysPath );
-
- if (
- ( pBuffer[0] >= 'A' && pBuffer[0] <= 'Z' ||
- pBuffer[0] >= 'a' && pBuffer[0] <= 'z' ) &&
- pBuffer[1] == ':' && ( nLen ==2 || nLen == 3 && pBuffer[2] == '\\' )
- )
- SetLastError( ERROR_ALREADY_EXISTS );
-
- error = MapError( GetLastError() );
- }
+ error = oslTranslateFileError( GetLastError() );
rtl_uString_release( strSysPath );
}
return error;
}
-//#####################################################
-oslFileError SAL_CALL osl_removeDirectory(rtl_uString* strPath)
+//#############################################
+#define osl_File_CopyRecursive 0x0001
+#define osl_File_CopyOverwrite 0x0002
+
+oslFileError SAL_CALL osl_copyFile( rtl_uString* strPath, rtl_uString *strDestPath )
{
- rtl_uString *strSysPath = NULL;
+ rtl_uString *strSysPath = NULL, *strSysDestPath = NULL;
oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
if ( osl_File_E_None == error )
- {
- if ( RemoveDirectory( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) )
- error = osl_File_E_None;
- else
- error = MapError( GetLastError() );
-
- rtl_uString_release( strSysPath );
- }
- return error;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_openDirectory(rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
-{
- oslFileError error;
+ error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False );
- if ( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase( strDirectoryPath->buffer, "file:///" ) )
- error = osl_openLocalRoot( strDirectoryPath, pDirectory );
- else
+ if ( osl_File_E_None == error )
{
- rtl_uString *strSysDirectoryPath = NULL;
-// WCHAR szCorrectedPathName[MAX_PATH];
- DWORD dwPathType;
-
- error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysDirectoryPath, sal_False );
-
- if ( osl_File_E_None != error )
- return error;
-
- // MT Perform05
- /*
- if ( GetCaseCorrectPathName( strSysDirectoryPath->buffer, szCorrectedPathName, MAX_PATH ) )
- {
- rtl_uString_newFromStr( &strSysDirectoryPath, szCorrectedPathName );
- }
- */
-
- dwPathType = IsValidFilePath( strSysDirectoryPath, NULL, VALIDATEPATH_NORMAL, NULL );
+ LPCTSTR src = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath ));
+ LPCTSTR dst = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath ));
- if ( dwPathType & PATHTYPE_IS_SERVER )
- {
- error = osl_openNetworkServer( strSysDirectoryPath, pDirectory );
- }
+ if ( CopyFile( src, dst, FALSE ) )
+ error = osl_File_E_None;
else
- error = osl_openFileDirectory( strSysDirectoryPath, pDirectory );
-
- rtl_uString_release( strSysDirectoryPath );
- }
- return error;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
-{
- Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
-
- /* Assume failure */
-
- if ( !pItem )
- return osl_File_E_INVAL;
-
- *pItem = NULL;
-
- if ( !pDirImpl )
- return osl_File_E_INVAL;
-
- switch ( pDirImpl->uType )
- {
- case DIRECTORYTYPE_LOCALROOT:
- return osl_getNextDrive( Directory, pItem, uHint );
- case DIRECTORYTYPE_NETROOT:
- return osl_getNextNetResource( Directory, pItem, uHint );
- case DIRECTORYTYPE_FILESYSTEM:
- return osl_getNextFileItem( Directory, pItem, uHint );
- default:
- return osl_File_E_INVAL;
+ error = oslTranslateFileError( GetLastError() );
}
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_closeDirectory(oslDirectory Directory)
-{
- Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
- oslFileError eError = osl_File_E_INVAL;
-
- if ( pDirImpl )
- {
- switch ( pDirImpl->uType )
- {
- case DIRECTORYTYPE_FILESYSTEM:
- eError = CloseDirectory( pDirImpl->hDirectory ) ? osl_File_E_None : MapError( GetLastError() );
- break;
- case DIRECTORYTYPE_LOCALROOT:
- eError = CloseLogicalDrivesEnum( pDirImpl->hEnumDrives ) ? osl_File_E_None : MapError( GetLastError() );
- break;
- case DIRECTORYTYPE_NETROOT:
- {
- DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
- eError = (err == NO_ERROR) ? osl_File_E_None : MapError(err);
- }
- break;
- default:
- OSL_ENSURE( 0, "Invalid directory type" );
- break;
- }
-
- rtl_freeMemory(pDirImpl);
- }
- return eError;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_getDirectoryItem(rtl_uString *strFilePath, oslDirectoryItem *pItem)
-{
- oslFileError error = osl_File_E_None;
- rtl_uString* strSysFilePath = NULL;
- PATHTYPE type = PATHTYPE_FILE;
- DWORD dwPathType;
-// TCHAR szCorrectedPathName[MAX_PATH];
-
- /* Assume failure */
-
- if ( !pItem )
- return osl_File_E_INVAL;
-
- *pItem = NULL;
-
-
- error = _osl_getSystemPathFromFileURL( strFilePath, &strSysFilePath, sal_False );
-
- if ( osl_File_E_None != error )
- return error;
-
- // MT: I can't imagine a case where this is good for!
- /*
- if ( GetCaseCorrectPathName( strSysFilePath->buffer, szCorrectedPathName, MAX_PATH ) )
- {
- rtl_uString_newFromStr( &strSysFilePath, szCorrectedPathName );
- }
- */
-
- dwPathType = IsValidFilePath( strSysFilePath, NULL, VALIDATEPATH_NORMAL, NULL );
-
- if ( dwPathType & PATHTYPE_IS_VOLUME )
- type = PATHTYPE_VOLUME;
- else if ( dwPathType & PATHTYPE_IS_SERVER )
- type = PATHTYPE_NETSERVER;
- else
- type = PATHTYPE_FILE;
-
- switch ( type )
- {
- case PATHTYPE_NETSERVER:
- {
- DirectoryItem_Impl* pItemImpl =
- reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
-
- if ( !pItemImpl )
- error = osl_File_E_NOMEM;
-
- if ( osl_File_E_None == error )
- {
- ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
- pItemImpl->uType = DIRECTORYITEM_SERVER;
-
- osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
-
- _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) );
-
- // Assign a title anyway
- {
- int iSrc = 2;
- int iDst = 0;
-
- while( iSrc < strSysFilePath->length && strSysFilePath->buffer[iSrc] && strSysFilePath->buffer[iSrc] != '\\' )
- {
- pItemImpl->FindData.cFileName[iDst++] = strSysFilePath->buffer[iSrc++];
- }
- }
-
- *pItem = pItemImpl;
- }
- }
- break;
- case PATHTYPE_VOLUME:
- {
- DirectoryItem_Impl* pItemImpl =
- reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
- if ( !pItemImpl )
- error = osl_File_E_NOMEM;
-
- if ( osl_File_E_None == error )
- {
- ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
- pItemImpl->uType = DIRECTORYITEM_DRIVE;
-
- osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
-
- _tcscpy( pItemImpl->cDriveString, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) );
- pItemImpl->cDriveString[0] = _toupper( pItemImpl->cDriveString[0] );
-
- if ( pItemImpl->cDriveString[_tcslen(pItemImpl->cDriveString) - 1] != '\\' )
- _tcscat( pItemImpl->cDriveString, TEXT( "\\" ) );
-
- *pItem = pItemImpl;
- }
- }
- break;
- case PATHTYPE_SYNTAXERROR:
- case PATHTYPE_NETROOT:
- case PATHTYPE_FILE:
- {
- HANDLE hFind;
- WIN32_FIND_DATA aFindData;
-
- if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
- rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );
-
- hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysFilePath)), &aFindData );
-
- if ( hFind != INVALID_HANDLE_VALUE )
- {
- DirectoryItem_Impl *pItemImpl =
- reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
-
- ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
- osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
-
- CopyMemory( &pItemImpl->FindData, &aFindData, sizeof(WIN32_FIND_DATA) );
- _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysFilePath)) );
-
- // MT: This costs 600ms startup time on fast v60x!
- // GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );
-
- pItemImpl->uType = DIRECTORYITEM_FILE;
- *pItem = pItemImpl;
- FindClose( hFind );
- }
- else
- error = MapError( GetLastError() );
- }
- break;
- }
-
- if ( strSysFilePath )
- rtl_uString_release( strSysFilePath );
+ if ( strSysPath )
+ rtl_uString_release( strSysPath );
+ if ( strSysDestPath )
+ rtl_uString_release( strSysDestPath );
return error;
}
-//#####################################################
-oslFileError SAL_CALL osl_acquireDirectoryItem( oslDirectoryItem Item )
-{
- DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
-
- if ( !pItemImpl )
- return osl_File_E_INVAL;
-
- pItemImpl->nRefCount++;
- return osl_File_E_None;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item )
-{
- DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
-
- if ( !pItemImpl )
- return osl_File_E_INVAL;
-
- if ( ! --pItemImpl->nRefCount )
- rtl_freeMemory( pItemImpl );
- return osl_File_E_None;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
-{
- if ( Handle )
- return osl_File_E_None;
- else
- return osl_File_E_INVAL;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
-{
- if ( Handle )
- return osl_File_E_None;
- else
- return osl_File_E_INVAL;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
-{
- if ( Handle )
- {
- rtl_uString_acquire( (rtl_uString *)Handle );
- return osl_File_E_None;
- }
- else
- return osl_File_E_INVAL;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
-{
- if ( Handle )
- {
- rtl_uString_release( (rtl_uString *)Handle );
- return osl_File_E_None;
- }
- else
- return osl_File_E_INVAL;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
-{
- if ( Handle && pstrPath )
- {
- rtl_uString_assign( pstrPath, (rtl_uString *)Handle );
- return osl_File_E_None;
- }
- else
- return osl_File_E_INVAL;
-}
-
-
-//##################################################################
-// FileURL functions
-//##################################################################
-
-
-//#####################################################
-oslFileError SAL_CALL osl_getFileURLFromSystemPath(
- rtl_uString* ustrPath, rtl_uString** pustrURL )
-{
- return _osl_getFileURLFromSystemPath( ustrPath, pustrURL );
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_getSystemPathFromFileURL(
- rtl_uString *ustrURL, rtl_uString **pustrPath)
-{
- return _osl_getSystemPathFromFileURL( ustrURL, pustrPath, sal_True );
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_searchFileURL(
- rtl_uString *ustrFileName,
- rtl_uString *ustrSystemSearchPath,
- rtl_uString **pustrPath)
+//#############################################
+oslFileError SAL_CALL osl_moveFile( rtl_uString* strPath, rtl_uString *strDestPath )
{
- rtl_uString *ustrUNCPath = NULL;
- rtl_uString *ustrSysPath = NULL;
- oslFileError error;
-
- /* First try to interpret the file name as an URL even a relative one */
- error = _osl_getSystemPathFromFileURL( ustrFileName, &ustrUNCPath, sal_True );
+ rtl_uString *strSysPath = NULL, *strSysDestPath = NULL;
+ oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
- /* So far we either have an UNC path or something invalid
- Now create a system path */
if ( osl_File_E_None == error )
- error = _osl_getSystemPathFromFileURL( ustrUNCPath, &ustrSysPath, sal_True );
+ error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False );
if ( osl_File_E_None == error )
{
- DWORD nBufferLength;
- DWORD dwResult;
- LPTSTR lpBuffer = NULL;
- LPTSTR lpszFilePart;
-
- /* Repeat calling SearchPath ...
- Start with MAX_PATH for the buffer. In most cases this
- will be enough and does not force the loop to runtwice */
- dwResult = MAX_PATH;
-
- do
- {
- /* If search path is empty use a NULL pointer instead according to MSDN documentation of SearchPath */
- LPCTSTR lpszSearchPath = ustrSystemSearchPath && ustrSystemSearchPath->length ? reinterpret_cast<LPCTSTR>(ustrSystemSearchPath->buffer) : NULL;
- LPCTSTR lpszSearchFile = reinterpret_cast<LPCTSTR>(ustrSysPath->buffer);
-
- /* Allocate space for buffer according to previous returned count of required chars */
- /* +1 is not neccessary if we follow MSDN documentation but for robustness we do so */
- nBufferLength = dwResult + 1;
- lpBuffer = lpBuffer ?
- reinterpret_cast<LPTSTR>(rtl_reallocateMemory(lpBuffer, nBufferLength * sizeof(TCHAR))) :
- reinterpret_cast<LPTSTR>(rtl_allocateMemory(nBufferLength * sizeof(TCHAR)));
+ LPCTSTR src = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath ));
+ LPCTSTR dst = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath ));
- dwResult = SearchPath( lpszSearchPath, lpszSearchFile, NULL, nBufferLength, lpBuffer, &lpszFilePart );
- } while ( dwResult && dwResult >= nBufferLength );
-
- /* ... until an error occures or buffer is large enough.
- dwResult == nBufferLength can not happen according to documentation but lets be robust ;-) */
-
- if ( dwResult )
- {
- rtl_uString_newFromStr( &ustrSysPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) );
- error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath );
- }
+ if ( MoveFileEx( src, dst, MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING ) )
+ error = osl_File_E_None;
else
- {
- WIN32_FIND_DATA aFindFileData;
- HANDLE hFind;
-
- /* Somthing went wrong, perhaps the path was absolute */
- error = MapError( GetLastError() );
-
- hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(ustrSysPath->buffer), &aFindFileData );
-
- if ( IsValidHandle(hFind) )
- {
- error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath );
- FindClose( hFind );
- }
- }
-
- rtl_freeMemory( lpBuffer );
+ error = oslTranslateFileError( GetLastError() );
}
-
- if ( ustrSysPath )
- rtl_uString_release( ustrSysPath );
- if ( ustrUNCPath )
- rtl_uString_release( ustrUNCPath );
+ if ( strSysPath )
+ rtl_uString_release( strSysPath );
+ if ( strSysDestPath )
+ rtl_uString_release( strSysDestPath );
return error;
}
-
-//#####################################################
-
-oslFileError SAL_CALL osl_getAbsoluteFileURL( rtl_uString* ustrBaseURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL )
-{
- oslFileError eError;
- rtl_uString *ustrRelSysPath = NULL;
- rtl_uString *ustrBaseSysPath = NULL;
-
- if ( ustrBaseURL && ustrBaseURL->length )
- {
- eError = _osl_getSystemPathFromFileURL( ustrBaseURL, &ustrBaseSysPath, sal_False );
- OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with relative or invalid base URL" );
-
- eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_True );
- }
- else
- {
- eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_False );
- OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" );
- }
-
- if ( !eError )
- {
- TCHAR szBuffer[MAX_PATH];
- TCHAR szCurrentDir[MAX_PATH];
- LPTSTR lpFilePart = NULL;
- DWORD dwResult;
-
-/*@@@ToDo
- Bad, bad hack, this only works if the base path
- really exists which is not necessary according
- to RFC2396
- The whole FileURL implementation should be merged
- with the rtl/uri class.
-*/
- if ( ustrBaseSysPath )
- {
- osl_acquireMutex( g_CurrentDirectoryMutex );
-
- GetCurrentDirectory( MAX_PATH, szCurrentDir );
- SetCurrentDirectory( reinterpret_cast<LPCTSTR>(ustrBaseSysPath->buffer) );
- }
-
- dwResult = GetFullPathName( reinterpret_cast<LPCTSTR>(ustrRelSysPath->buffer), MAX_PATH, szBuffer, &lpFilePart );
-
- if ( ustrBaseSysPath )
- {
- SetCurrentDirectory( szCurrentDir );
-
- osl_releaseMutex( g_CurrentDirectoryMutex );
- }
-
- if ( dwResult )
- {
- if ( dwResult >= MAX_PATH )
- eError = osl_File_E_INVAL;
- else
- {
- rtl_uString *ustrAbsSysPath = NULL;
-
- rtl_uString_newFromStr( &ustrAbsSysPath, reinterpret_cast<const sal_Unicode*>(szBuffer) );
-
- eError = osl_getFileURLFromSystemPath( ustrAbsSysPath, pustrAbsoluteURL );
-
- if ( ustrAbsSysPath )
- rtl_uString_release( ustrAbsSysPath );
- }
- }
- else
- eError = MapError( GetLastError() );
- }
-
- if ( ustrBaseSysPath )
- rtl_uString_release( ustrBaseSysPath );
-
- if ( ustrRelSysPath )
- rtl_uString_release( ustrRelSysPath );
-
- return eError;
-}
-
-//#####################################################
-oslFileError SAL_CALL osl_getCanonicalName( rtl_uString *strRequested, rtl_uString **strValid )
-{
- rtl_uString_newFromString(strValid, strRequested);
- return osl_File_E_None;
-}
diff --git a/sal/osl/w32/file_dirvol.cxx b/sal/osl/w32/file_dirvol.cxx
new file mode 100644
index 000000000..15cade63e
--- /dev/null
+++ b/sal/osl/w32/file_dirvol.cxx
@@ -0,0 +1,1774 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: file.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * 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_url.h"
+#include "file_error.h"
+#include "path_helper.hxx"
+
+#include "osl/diagnose.h"
+#include "osl/time.h"
+#include "rtl/alloc.h"
+#include "rtl/ustring.hxx"
+
+#include <tchar.h>
+
+//#####################################################
+#define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
+
+static const wchar_t UNC_PREFIX[] = L"\\\\";
+static const wchar_t BACKSLASH = '\\';
+static const wchar_t SLASH = '/';
+
+//#####################################################
+extern "C" BOOL TimeValueToFileTime(const TimeValue *cpTimeVal, FILETIME *pFTime)
+{
+ SYSTEMTIME BaseSysTime;
+ FILETIME BaseFileTime;
+ FILETIME FTime;
+ __int64 localTime;
+ BOOL fSuccess = FALSE;
+
+ BaseSysTime.wYear = 1970;
+ BaseSysTime.wMonth = 1;
+ BaseSysTime.wDayOfWeek = 0;
+ BaseSysTime.wDay = 1;
+ BaseSysTime.wHour = 0;
+ BaseSysTime.wMinute = 0;
+ BaseSysTime.wSecond = 0;
+ BaseSysTime.wMilliseconds = 0;
+
+ if (cpTimeVal==NULL)
+ return fSuccess;
+
+ if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
+ {
+ __int64 timeValue;
+ localTime=cpTimeVal->Seconds*(__int64)10000000+cpTimeVal->Nanosec/100;
+ *(__int64 *)&FTime=localTime;
+ fSuccess = 0 <= (timeValue= *((__int64 *)&BaseFileTime) + *((__int64 *) &FTime));
+ if (fSuccess)
+ *(__int64 *)pFTime=timeValue;
+ }
+ return fSuccess;
+}
+
+//#####################################################
+extern "C" BOOL FileTimeToTimeValue(const FILETIME *cpFTime, TimeValue *pTimeVal)
+{
+ SYSTEMTIME BaseSysTime;
+ FILETIME BaseFileTime;
+ BOOL fSuccess = FALSE; /* Assume failure */
+
+ BaseSysTime.wYear = 1970;
+ BaseSysTime.wMonth = 1;
+ BaseSysTime.wDayOfWeek = 0;
+ BaseSysTime.wDay = 1;
+ BaseSysTime.wHour = 0;
+ BaseSysTime.wMinute = 0;
+ BaseSysTime.wSecond = 0;
+ BaseSysTime.wMilliseconds = 0;
+
+ if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
+ {
+ __int64 Value;
+
+ fSuccess = 0 <= (Value = *((__int64 *)cpFTime) - *((__int64 *)&BaseFileTime));
+
+ if ( fSuccess )
+ {
+ pTimeVal->Seconds = (unsigned long) (Value / 10000000L);
+ pTimeVal->Nanosec = (unsigned long)((Value % 10000000L) * 100);
+ }
+ }
+ return fSuccess;
+}
+
+//#####################################################
+namespace /* private */
+{
+ //#####################################################
+ struct Component
+ {
+ Component() :
+ begin_(0), end_(0)
+ {}
+
+ bool isPresent() const
+ { return (static_cast<sal_IntPtr>(end_ - begin_) > 0); }
+
+ const sal_Unicode* begin_;
+ const sal_Unicode* end_;
+ };
+
+ //#####################################################
+ struct UNCComponents
+ {
+ Component server_;
+ Component share_;
+ Component resource_;
+ };
+
+ //#####################################################
+ inline bool is_UNC_path(const sal_Unicode* path)
+ { return (0 == wcsncmp(UNC_PREFIX, reinterpret_cast<LPCWSTR>(path), ELEMENTS_OF_ARRAY(UNC_PREFIX) - 1)); }
+
+ //#####################################################
+ inline bool is_UNC_path(const rtl::OUString& path)
+ { return is_UNC_path(path.getStr()); }
+
+ //#####################################################
+ void parse_UNC_path(const sal_Unicode* path, UNCComponents* puncc)
+ {
+ OSL_PRECOND(is_UNC_path(path), "Precondition violated: No UNC path");
+ OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) != -1, "Path must not contain slashes");
+
+ const sal_Unicode* pend = path + rtl_ustr_getLength(path);
+ const sal_Unicode* ppos = path + 2;
+
+ puncc->server_.begin_ = ppos;
+ while ((ppos < pend) && (*ppos != BACKSLASH))
+ ppos++;
+
+ puncc->server_.end_ = ppos;
+
+ if (BACKSLASH == *ppos)
+ {
+ puncc->share_.begin_ = ++ppos;
+ while ((ppos < pend) && (*ppos != BACKSLASH))
+ ppos++;
+
+ puncc->share_.end_ = ppos;
+
+ if (BACKSLASH == *ppos)
+ {
+ puncc->resource_.begin_ = ++ppos;
+ while (ppos < pend)
+ ppos++;
+
+ puncc->resource_.end_ = ppos;
+ }
+ }
+
+ OSL_POSTCOND(puncc->server_.isPresent() && puncc->share_.isPresent(), \
+ "Postcondition violated: Invalid UNC path detected");
+ }
+
+ //#####################################################
+ void parse_UNC_path(const rtl::OUString& path, UNCComponents* puncc)
+ { parse_UNC_path(path.getStr(), puncc); }
+
+
+ //#####################################################
+ bool has_path_parent(const sal_Unicode* path)
+ {
+ // Has the given path a parent or are we already there,
+ // e.g. 'c:\' or '\\server\share\'?
+
+ bool has_parent = false;
+ if (is_UNC_path(path))
+ {
+ UNCComponents unc_comp;
+ parse_UNC_path(path, &unc_comp);
+ has_parent = unc_comp.resource_.isPresent();
+ }
+ else
+ {
+ has_parent = !osl::systemPathIsLogicalDrivePattern(path);
+ }
+ return has_parent;
+ }
+
+ //#####################################################
+ inline bool has_path_parent(const rtl::OUString& path)
+ { return has_path_parent(path.getStr()); }
+
+} // end namespace private
+
+//#####################################################
+// volume handling functions
+//#####################################################
+
+//#####################################################
+oslFileError SAL_CALL osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
+{
+ if ( Handle )
+ return osl_File_E_None;
+ else
+ return osl_File_E_INVAL;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
+{
+ if ( Handle )
+ return osl_File_E_None;
+ else
+ return osl_File_E_INVAL;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
+{
+ if ( Handle )
+ {
+ rtl_uString_acquire( (rtl_uString *)Handle );
+ return osl_File_E_None;
+ }
+ else
+ return osl_File_E_INVAL;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
+{
+ if ( Handle )
+ {
+ rtl_uString_release( (rtl_uString *)Handle );
+ return osl_File_E_None;
+ }
+ else
+ return osl_File_E_INVAL;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
+{
+ if ( Handle && pstrPath )
+ {
+ rtl_uString_assign( pstrPath, (rtl_uString *)Handle );
+ return osl_File_E_None;
+ }
+ else
+ return osl_File_E_INVAL;
+}
+
+//##################################################################
+// directory handling functions
+//##################################################################
+
+#define DIRECTORYITEM_DRIVE 0
+#define DIRECTORYITEM_FILE 1
+#define DIRECTORYITEM_SERVER 2
+
+struct DirectoryItem_Impl
+{
+ UINT uType;
+ union {
+ WIN32_FIND_DATA FindData;
+ TCHAR cDriveString[MAX_PATH];
+ };
+ TCHAR szFullPath[MAX_PATH];
+ BOOL bFullPathNormalized;
+ int nRefCount;
+};
+
+//#####################################################
+
+#define DIRECTORYTYPE_LOCALROOT 0
+#define DIRECTORYTYPE_NETROOT 1
+#define DIRECTORYTYPE_NETRESORCE 2
+#define DIRECTORYTYPE_FILESYSTEM 3
+
+struct Directory_Impl
+{
+ UINT uType;
+ union {
+ HANDLE hDirectory;
+ HANDLE hEnumDrives;
+ };
+ TCHAR szDirectoryPath[MAX_PATH];
+};
+
+//#####################################################
+
+typedef struct tagDRIVEENUM
+{
+ LPCTSTR lpIdent;
+ TCHAR cBuffer[/*('Z' - 'A' + 1) * sizeof("A:\\") + 1*/256];
+ LPCTSTR lpCurrent;
+} DRIVEENUM, * PDRIVEENUM, FAR * LPDRIVEENUM;
+
+//#####################################################
+
+static HANDLE WINAPI OpenLogicalDrivesEnum(void)
+{
+ LPDRIVEENUM pEnum = (LPDRIVEENUM)HeapAlloc( GetProcessHeap(), 0, sizeof(DRIVEENUM) );
+ if ( pEnum )
+ {
+ DWORD dwNumCopied = GetLogicalDriveStrings( (sizeof(pEnum->cBuffer) - 1) / sizeof(TCHAR), pEnum->cBuffer );
+
+ if ( dwNumCopied && dwNumCopied < sizeof(pEnum->cBuffer) / sizeof(TCHAR) )
+ {
+ pEnum->lpCurrent = pEnum->cBuffer;
+ pEnum->lpIdent = L"tagDRIVEENUM";
+ }
+ else
+ {
+ HeapFree( GetProcessHeap(), 0, pEnum );
+ pEnum = NULL;
+ }
+ }
+ return pEnum ? (HANDLE)pEnum : INVALID_HANDLE_VALUE;
+}
+
+//#####################################################
+static BOOL WINAPI EnumLogicalDrives(HANDLE hEnum, LPTSTR lpBuffer)
+{
+ BOOL fSuccess = FALSE;
+ LPDRIVEENUM pEnum = (LPDRIVEENUM)hEnum;
+
+ if ( pEnum )
+ {
+ int nLen = _tcslen( pEnum->lpCurrent );
+
+ if ( nLen )
+ {
+ CopyMemory( lpBuffer, pEnum->lpCurrent, (nLen + 1) * sizeof(TCHAR) );
+ pEnum->lpCurrent += nLen + 1;
+ fSuccess = TRUE;
+ }
+ else
+ SetLastError( ERROR_NO_MORE_FILES );
+ }
+ else
+ SetLastError( ERROR_INVALID_HANDLE );
+
+ return fSuccess;
+}
+
+//#####################################################
+static BOOL WINAPI CloseLogicalDrivesEnum(HANDLE hEnum)
+{
+ BOOL fSuccess = FALSE;
+ LPDRIVEENUM pEnum = (LPDRIVEENUM)hEnum;
+
+ if ( pEnum )
+ {
+ HeapFree( GetProcessHeap(), 0, pEnum );
+ fSuccess = TRUE;
+ }
+ else
+ SetLastError( ERROR_INVALID_HANDLE );
+
+ return fSuccess;
+}
+
+//#####################################################
+typedef struct tagDIRECTORY
+{
+ HANDLE hFind;
+ WIN32_FIND_DATA aFirstData;
+} DIRECTORY, *PDIRECTORY, FAR *LPDIRECTORY;
+
+//#####################################################
+static HANDLE WINAPI OpenDirectory(LPCTSTR lpszPath)
+{
+ LPDIRECTORY pDirectory = (LPDIRECTORY)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY));
+
+ if (pDirectory)
+ {
+ TCHAR szFileMask[MAX_PATH];
+ int nLen;
+
+ _tcscpy( szFileMask, lpszPath );
+ nLen = _tcslen( szFileMask );
+
+ if (nLen && szFileMask[nLen-1] != '\\')
+ _tcscat(szFileMask, TEXT("\\*.*"));
+ else
+ _tcscat(szFileMask, TEXT("*.*"));
+
+ pDirectory->hFind = FindFirstFile(szFileMask, &pDirectory->aFirstData);
+
+ if (!IsValidHandle(pDirectory->hFind))
+ {
+ if ( GetLastError() != ERROR_NO_MORE_FILES )
+ {
+ HeapFree(GetProcessHeap(), 0, pDirectory);
+ pDirectory = NULL;
+ }
+ }
+ }
+ return (HANDLE)pDirectory;
+}
+
+//#####################################################
+BOOL WINAPI EnumDirectory(HANDLE hDirectory, LPWIN32_FIND_DATA pFindData)
+{
+ BOOL fSuccess = FALSE;
+ LPDIRECTORY pDirectory = (LPDIRECTORY)hDirectory;
+
+ if ( pDirectory )
+ {
+ BOOL fValid;
+
+ do
+ {
+ if ( pDirectory->aFirstData.cFileName[0] )
+ {
+ *pFindData = pDirectory->aFirstData;
+ fSuccess = TRUE;
+ pDirectory->aFirstData.cFileName[0] = 0;
+ }
+ else if ( IsValidHandle( pDirectory->hFind ) )
+ fSuccess = FindNextFile( pDirectory->hFind, pFindData );
+ else
+ {
+ fSuccess = FALSE;
+ SetLastError( ERROR_NO_MORE_FILES );
+ }
+
+ fValid = fSuccess && _tcscmp( TEXT("."), pFindData->cFileName ) != 0 && _tcscmp( TEXT(".."), pFindData->cFileName ) != 0;
+
+ } while( fSuccess && !fValid );
+ }
+ else
+ SetLastError( ERROR_INVALID_HANDLE );
+
+ return fSuccess;
+}
+
+//#####################################################
+static BOOL WINAPI CloseDirectory(HANDLE hDirectory)
+{
+ BOOL fSuccess = FALSE;
+ LPDIRECTORY pDirectory = (LPDIRECTORY)hDirectory;
+
+ if (pDirectory)
+ {
+ if (IsValidHandle(pDirectory->hFind))
+ fSuccess = FindClose(pDirectory->hFind);
+
+ fSuccess = HeapFree(GetProcessHeap(), 0, pDirectory) && fSuccess;
+ }
+ else
+ SetLastError(ERROR_INVALID_HANDLE);
+
+ return fSuccess;
+}
+
+//#####################################################
+static oslFileError osl_openLocalRoot(
+ rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
+{
+ rtl_uString *strSysPath = NULL;
+ oslFileError error;
+
+ if ( !pDirectory )
+ return osl_File_E_INVAL;
+
+ *pDirectory = NULL;
+
+ error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysPath, sal_False );
+ if ( osl_File_E_None == error )
+ {
+ Directory_Impl *pDirImpl;
+
+ pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory( sizeof(Directory_Impl)));
+ _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysPath)) );
+
+ /* Append backslash if neccessary */
+
+ /* @@@ToDo
+ use function ensure backslash
+ */
+ if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' )
+ _tcscat( pDirImpl->szDirectoryPath, L"\\" );
+
+ pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
+ pDirImpl->hEnumDrives = OpenLogicalDrivesEnum();
+
+ /* @@@ToDo
+ Use IsValidHandle(...)
+ */
+ if ( pDirImpl->hEnumDrives != INVALID_HANDLE_VALUE )
+ {
+ *pDirectory = (oslDirectory)pDirImpl;
+ error = osl_File_E_None;
+ }
+ else
+ {
+ if ( pDirImpl )
+ rtl_freeMemory(pDirImpl);
+
+ error = oslTranslateFileError( GetLastError() );
+ }
+
+ rtl_uString_release( strSysPath );
+ }
+ return error;
+}
+
+//#####################################################
+static oslFileError SAL_CALL osl_openFileDirectory(
+ rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
+{
+ oslFileError error = osl_File_E_None;
+
+ if ( !pDirectory )
+ return osl_File_E_INVAL;
+ *pDirectory = NULL;
+
+ Directory_Impl *pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
+ _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strDirectoryPath)) );
+
+ /* Append backslash if neccessary */
+
+ /* @@@ToDo
+ use function ensure backslash
+ */
+ if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' )
+ _tcscat( pDirImpl->szDirectoryPath, L"\\" );
+
+ pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
+ pDirImpl->hDirectory = OpenDirectory( pDirImpl->szDirectoryPath );
+
+ if ( !pDirImpl->hDirectory )
+ {
+ error = oslTranslateFileError( GetLastError() );
+
+ rtl_freeMemory(pDirImpl), pDirImpl = 0;
+ }
+
+ *pDirectory = (oslDirectory)(pDirImpl);
+ return error;
+}
+
+//#####################################################
+static oslFileError SAL_CALL osl_openNetworkServer(
+ rtl_uString *strSysDirPath, oslDirectory *pDirectory)
+{
+ NETRESOURCEW aNetResource;
+ HANDLE hEnum;
+ DWORD dwError;
+
+ ZeroMemory( &aNetResource, sizeof(aNetResource) );
+
+ aNetResource.lpRemoteName = reinterpret_cast<LPWSTR>(strSysDirPath->buffer);
+
+ dwError = WNetOpenEnumW(
+ RESOURCE_GLOBALNET,
+ RESOURCETYPE_DISK,
+ RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER,
+ &aNetResource,
+ &hEnum );
+
+ if ( ERROR_SUCCESS == dwError )
+ {
+ Directory_Impl *pDirImpl;
+
+ pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
+ pDirImpl->uType = DIRECTORYTYPE_NETROOT;
+ pDirImpl->hDirectory = hEnum;
+ *pDirectory = (oslDirectory)pDirImpl;
+ }
+ return oslTranslateFileError( dwError );
+}
+
+//#############################################
+static DWORD create_dir_with_callback(
+ rtl_uString * dir_path,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ // Create the specified directory and call the
+ // user specified callback function. On success
+ // the function returns ERROR_SUCCESS else a Win32 error code.
+
+ if (CreateDirectory(reinterpret_cast<LPCTSTR>(dir_path->buffer), NULL))
+ {
+ if (aDirectoryCreationCallbackFunc)
+ {
+ rtl::OUString url;
+ _osl_getFileURLFromSystemPath(dir_path, &(url.pData));
+ aDirectoryCreationCallbackFunc(pData, url.pData);
+ }
+ return ERROR_SUCCESS;
+ }
+ return GetLastError();
+}
+
+//#############################################
+static int path_make_parent(sal_Unicode* path)
+{
+ /* Cut off the last part of the given path to
+ get the parent only, e.g. 'c:\dir\subdir' ->
+ 'c:\dir' or '\\share\sub\dir' -> '\\share\sub'
+ @return The position where the path has been cut
+ off (this is the posistion of the last backslash).
+ If there are no more parents 0 will be returned,
+ e.g. 'c:\' or '\\Share' have no more parents */
+
+ OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) != -1, "Path must not contain slashes");
+ OSL_PRECOND(has_path_parent(path), "Path must have a parent");
+
+ sal_Unicode* pos_last_backslash = path + rtl_ustr_lastIndexOfChar(path, BACKSLASH);
+ *pos_last_backslash = 0;
+ return (pos_last_backslash - path);
+}
+
+//#############################################
+static DWORD create_dir_recursively_(
+ rtl_uString * dir_path,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ OSL_PRECOND(
+ rtl_ustr_lastIndexOfChar_WithLength(dir_path->buffer, dir_path->length, BACKSLASH) != dir_path->length,
+ "Path must not end with a backslash");
+
+ DWORD w32_error = create_dir_with_callback(
+ dir_path, aDirectoryCreationCallbackFunc, pData);
+ if (w32_error == ERROR_SUCCESS)
+ return ERROR_SUCCESS;
+
+ if ((w32_error != ERROR_PATH_NOT_FOUND) || !has_path_parent(dir_path->buffer))
+ return w32_error;
+
+ int pos = path_make_parent(dir_path->buffer); // dir_path->buffer[pos] = 0, restore below
+
+ w32_error = create_dir_recursively_(
+ dir_path, aDirectoryCreationCallbackFunc, pData);
+
+ dir_path->buffer[pos] = BACKSLASH; // restore
+
+ if (ERROR_SUCCESS != w32_error)
+ return w32_error;
+
+ return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
+}
+
+//#############################################
+oslFileError SAL_CALL osl_createDirectoryPath(
+ rtl_uString* aDirectoryUrl,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ if (aDirectoryUrl == NULL)
+ return osl_File_E_INVAL;
+
+ rtl::OUString sys_path;
+ oslFileError osl_error =
+ _osl_getSystemPathFromFileURL(aDirectoryUrl, &sys_path.pData, sal_False);
+
+ if (osl_error != osl_File_E_None)
+ return osl_error;
+
+ osl::systemPathRemoveSeparator(sys_path);
+
+ // const_cast because sys_path is a local copy
+ // which we want to modify inplace instead of
+ // coyp it into another buffer on the heap again
+ return oslTranslateFileError(create_dir_recursively_(
+ sys_path.pData, aDirectoryCreationCallbackFunc, pData));
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_createDirectory(rtl_uString* strPath)
+{
+ rtl_uString *strSysPath = NULL;
+ oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
+
+ if ( osl_File_E_None == error )
+ {
+ if ( CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), NULL ) )
+ error = osl_File_E_None;
+/*@@@ToDo
+ The else case is a hack because the ucb or the webtop had some
+ problems with the error code that CreateDirectory returns in
+ case the path is only a logical drive, should be removed!
+*/
+ else
+ {
+ const sal_Unicode *pBuffer = rtl_uString_getStr( strSysPath );
+ sal_Int32 nLen = rtl_uString_getLength( strSysPath );
+
+ if (
+ ( pBuffer[0] >= 'A' && pBuffer[0] <= 'Z' ||
+ pBuffer[0] >= 'a' && pBuffer[0] <= 'z' ) &&
+ pBuffer[1] == ':' && ( nLen ==2 || nLen == 3 && pBuffer[2] == '\\' )
+ )
+ SetLastError( ERROR_ALREADY_EXISTS );
+
+ error = oslTranslateFileError( GetLastError() );
+ }
+
+ rtl_uString_release( strSysPath );
+ }
+ return error;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_removeDirectory(rtl_uString* strPath)
+{
+ rtl_uString *strSysPath = NULL;
+ oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
+
+ if ( osl_File_E_None == error )
+ {
+ if ( RemoveDirectory( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) )
+ error = osl_File_E_None;
+ else
+ error = oslTranslateFileError( GetLastError() );
+
+ rtl_uString_release( strSysPath );
+ }
+ return error;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_openDirectory(rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
+{
+ oslFileError error;
+
+ if ( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase( strDirectoryPath->buffer, "file:///" ) )
+ error = osl_openLocalRoot( strDirectoryPath, pDirectory );
+ else
+ {
+ rtl_uString *strSysDirectoryPath = NULL;
+ DWORD dwPathType;
+
+ error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysDirectoryPath, sal_False );
+
+ if ( osl_File_E_None != error )
+ return error;
+
+ dwPathType = IsValidFilePath( strSysDirectoryPath, NULL, VALIDATEPATH_NORMAL, NULL );
+
+ if ( dwPathType & PATHTYPE_IS_SERVER )
+ {
+ error = osl_openNetworkServer( strSysDirectoryPath, pDirectory );
+ }
+ else
+ error = osl_openFileDirectory( strSysDirectoryPath, pDirectory );
+
+ rtl_uString_release( strSysDirectoryPath );
+ }
+ return error;
+}
+
+//#####################################################
+static oslFileError SAL_CALL osl_getNextNetResource(
+ oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
+{
+ Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
+ DirectoryItem_Impl *pItemImpl = NULL;
+ BYTE buffer[16384];
+ LPNETRESOURCEW lpNetResource = (LPNETRESOURCEW)buffer;
+ DWORD dwError, dwCount, dwBufSize;
+
+ uHint = uHint; /* to get no warning */
+
+ if ( !pItem )
+ return osl_File_E_INVAL;
+ *pItem = NULL;
+
+ if ( !pDirImpl )
+ return osl_File_E_INVAL;
+
+ dwCount = 1;
+ dwBufSize = sizeof(buffer);
+ dwError = WNetEnumResource( pDirImpl->hDirectory, &dwCount, lpNetResource, &dwBufSize );
+
+ switch ( dwError )
+ {
+ case NO_ERROR:
+ case ERROR_MORE_DATA:
+ {
+ pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+ if ( !pItemImpl )
+ return osl_File_E_NOMEM;
+
+ ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_DRIVE;
+ osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
+
+ wcscpy( pItemImpl->cDriveString, lpNetResource->lpRemoteName );
+
+ *pItem = pItemImpl;
+ }
+ return osl_File_E_None;
+ case ERROR_NO_MORE_ITEMS:
+ return osl_File_E_NOENT;
+ default:
+ return oslTranslateFileError( dwError );
+ }
+}
+
+//#####################################################
+static oslFileError SAL_CALL osl_getNextDrive(
+ oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
+{
+ Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
+ DirectoryItem_Impl *pItemImpl = NULL;
+ BOOL fSuccess;
+
+ uHint = uHint; /* avoid warnings */
+
+ if ( !pItem )
+ return osl_File_E_INVAL;
+ *pItem = NULL;
+
+ if ( !pDirImpl )
+ return osl_File_E_INVAL;
+
+ pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+ if ( !pItemImpl )
+ return osl_File_E_NOMEM;
+
+ ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_DRIVE;
+ osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
+ fSuccess = EnumLogicalDrives( pDirImpl->hEnumDrives, pItemImpl->cDriveString );
+
+ if ( fSuccess )
+ {
+ *pItem = pItemImpl;
+ return osl_File_E_None;
+ }
+ else
+ {
+ rtl_freeMemory( pItemImpl );
+ return oslTranslateFileError( GetLastError() );
+ }
+}
+
+//#####################################################
+static oslFileError SAL_CALL osl_getNextFileItem(
+ oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
+{
+ Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
+ DirectoryItem_Impl *pItemImpl = NULL;
+ BOOL fFound;
+
+ uHint = uHint; /* avoid warnings */
+
+ if ( !pItem )
+ return osl_File_E_INVAL;
+ *pItem = NULL;
+
+ if ( !pDirImpl )
+ return osl_File_E_INVAL;
+
+ pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+ if ( !pItemImpl )
+ return osl_File_E_NOMEM;
+
+ memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
+ fFound = EnumDirectory( pDirImpl->hDirectory, &pItemImpl->FindData );
+
+ if ( fFound )
+ {
+ pItemImpl->uType = DIRECTORYITEM_FILE;
+ pItemImpl->nRefCount = 1;
+ _tcscpy( pItemImpl->szFullPath, pDirImpl->szDirectoryPath );
+ _tcscat( pItemImpl->szFullPath, pItemImpl->FindData.cFileName );
+ pItemImpl->bFullPathNormalized = FALSE;
+ *pItem = (oslDirectoryItem)pItemImpl;
+ return osl_File_E_None;
+ }
+ else
+ {
+ rtl_freeMemory( pItemImpl );
+ return oslTranslateFileError( GetLastError() );
+ }
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_getNextDirectoryItem(
+ oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
+{
+ Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
+
+ /* Assume failure */
+
+ if ( !pItem )
+ return osl_File_E_INVAL;
+ *pItem = NULL;
+
+ if ( !pDirImpl )
+ return osl_File_E_INVAL;
+
+ switch ( pDirImpl->uType )
+ {
+ case DIRECTORYTYPE_LOCALROOT:
+ return osl_getNextDrive( Directory, pItem, uHint );
+ case DIRECTORYTYPE_NETROOT:
+ return osl_getNextNetResource( Directory, pItem, uHint );
+ case DIRECTORYTYPE_FILESYSTEM:
+ return osl_getNextFileItem( Directory, pItem, uHint );
+ default:
+ return osl_File_E_INVAL;
+ }
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_closeDirectory(oslDirectory Directory)
+{
+ Directory_Impl *pDirImpl = (Directory_Impl *)Directory;
+ oslFileError eError = osl_File_E_INVAL;
+
+ if ( pDirImpl )
+ {
+ switch ( pDirImpl->uType )
+ {
+ case DIRECTORYTYPE_FILESYSTEM:
+ eError = CloseDirectory( pDirImpl->hDirectory ) ? osl_File_E_None : oslTranslateFileError( GetLastError() );
+ break;
+ case DIRECTORYTYPE_LOCALROOT:
+ eError = CloseLogicalDrivesEnum( pDirImpl->hEnumDrives ) ? osl_File_E_None : oslTranslateFileError( GetLastError() );
+ break;
+ case DIRECTORYTYPE_NETROOT:
+ {
+ DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
+ eError = (err == NO_ERROR) ? osl_File_E_None : oslTranslateFileError(err);
+ }
+ break;
+ default:
+ OSL_ENSURE( 0, "Invalid directory type" );
+ break;
+ }
+
+ rtl_freeMemory(pDirImpl);
+ }
+ return eError;
+}
+
+//#####################################################
+/* Different types of paths */
+typedef enum _PATHTYPE
+{
+ PATHTYPE_SYNTAXERROR = 0,
+ PATHTYPE_NETROOT,
+ PATHTYPE_NETSERVER,
+ PATHTYPE_VOLUME,
+ PATHTYPE_FILE
+} PATHTYPE;
+
+oslFileError SAL_CALL osl_getDirectoryItem(rtl_uString *strFilePath, oslDirectoryItem *pItem)
+{
+ oslFileError error = osl_File_E_None;
+ rtl_uString* strSysFilePath = NULL;
+ PATHTYPE type = PATHTYPE_FILE;
+ DWORD dwPathType;
+
+ /* Assume failure */
+
+ if ( !pItem )
+ return osl_File_E_INVAL;
+
+ *pItem = NULL;
+
+
+ error = _osl_getSystemPathFromFileURL( strFilePath, &strSysFilePath, sal_False );
+
+ if ( osl_File_E_None != error )
+ return error;
+
+ dwPathType = IsValidFilePath( strSysFilePath, NULL, VALIDATEPATH_NORMAL, NULL );
+
+ if ( dwPathType & PATHTYPE_IS_VOLUME )
+ type = PATHTYPE_VOLUME;
+ else if ( dwPathType & PATHTYPE_IS_SERVER )
+ type = PATHTYPE_NETSERVER;
+ else
+ type = PATHTYPE_FILE;
+
+ switch ( type )
+ {
+ case PATHTYPE_NETSERVER:
+ {
+ DirectoryItem_Impl* pItemImpl =
+ reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+
+ if ( !pItemImpl )
+ error = osl_File_E_NOMEM;
+
+ if ( osl_File_E_None == error )
+ {
+ ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_SERVER;
+
+ osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
+
+ _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) );
+
+ // Assign a title anyway
+ {
+ int iSrc = 2;
+ int iDst = 0;
+
+ while( iSrc < strSysFilePath->length && strSysFilePath->buffer[iSrc] && strSysFilePath->buffer[iSrc] != '\\' )
+ {
+ pItemImpl->FindData.cFileName[iDst++] = strSysFilePath->buffer[iSrc++];
+ }
+ }
+
+ *pItem = pItemImpl;
+ }
+ }
+ break;
+ case PATHTYPE_VOLUME:
+ {
+ DirectoryItem_Impl* pItemImpl =
+ reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+
+ if ( !pItemImpl )
+ error = osl_File_E_NOMEM;
+
+ if ( osl_File_E_None == error )
+ {
+ ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_DRIVE;
+
+ osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
+
+ _tcscpy( pItemImpl->cDriveString, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) );
+ pItemImpl->cDriveString[0] = _toupper( pItemImpl->cDriveString[0] );
+
+ if ( pItemImpl->cDriveString[_tcslen(pItemImpl->cDriveString) - 1] != '\\' )
+ _tcscat( pItemImpl->cDriveString, TEXT( "\\" ) );
+
+ *pItem = pItemImpl;
+ }
+ }
+ break;
+ case PATHTYPE_SYNTAXERROR:
+ case PATHTYPE_NETROOT:
+ case PATHTYPE_FILE:
+ {
+ HANDLE hFind;
+ WIN32_FIND_DATA aFindData;
+
+ if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
+ rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );
+
+ hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysFilePath)), &aFindData );
+
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ DirectoryItem_Impl *pItemImpl =
+ reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+
+ ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
+ osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
+
+ CopyMemory( &pItemImpl->FindData, &aFindData, sizeof(WIN32_FIND_DATA) );
+ _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysFilePath)) );
+
+ // MT: This costs 600ms startup time on fast v60x!
+ // GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );
+
+ pItemImpl->uType = DIRECTORYITEM_FILE;
+ *pItem = pItemImpl;
+ FindClose( hFind );
+ }
+ else
+ error = oslTranslateFileError( GetLastError() );
+ }
+ break;
+ }
+
+ if ( strSysFilePath )
+ rtl_uString_release( strSysFilePath );
+
+ return error;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_acquireDirectoryItem( oslDirectoryItem Item )
+{
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ pItemImpl->nRefCount++;
+ return osl_File_E_None;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item )
+{
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ if ( ! --pItemImpl->nRefCount )
+ rtl_freeMemory( pItemImpl );
+ return osl_File_E_None;
+}
+
+//#####################################################
+// volume / file info handling functions
+//#####################################################
+
+//#####################################################
+static inline bool is_floppy_A_present()
+{ return (GetLogicalDrives() & 1); }
+
+//#####################################################
+static inline bool is_floppy_B_present()
+{ return (GetLogicalDrives() & 2); }
+
+//#####################################################
+bool is_floppy_volume_mount_point(const rtl::OUString& path)
+{
+ // determines if a volume mount point shows to a floppy
+ // disk by comparing the unique volume names
+ static const LPWSTR FLOPPY_A = L"A:\\";
+ static const LPWSTR FLOPPY_B = L"B:\\";
+
+ rtl::OUString p(path);
+ osl::systemPathEnsureSeparator(p);
+
+ TCHAR vn[51];
+ if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
+ {
+ TCHAR vnfloppy[51];
+ if (is_floppy_A_present() &&
+ GetVolumeNameForVolumeMountPoint(FLOPPY_A, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
+ (0 == wcscmp(vn, vnfloppy)))
+ return true;
+
+ if (is_floppy_B_present() &&
+ GetVolumeNameForVolumeMountPoint(FLOPPY_B, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
+ (0 == wcscmp(vn, vnfloppy)))
+ return true;
+ }
+ return false;
+}
+
+//################################################
+static bool is_floppy_drive(const rtl::OUString& path)
+{
+ static const LPWSTR FLOPPY_DRV_LETTERS = TEXT("AaBb");
+
+ // we must take into account that even a floppy
+ // drive may be mounted to a directory so checking
+ // for the drive letter alone is not sufficient
+ // we must compare the unique volume name with
+ // that of the available floppy disks
+
+ const sal_Unicode* pszPath = path.getStr();
+ return ((wcschr(FLOPPY_DRV_LETTERS, pszPath[0]) && (L':' == pszPath[1])) || is_floppy_volume_mount_point(path));
+}
+
+//#####################################################
+static bool is_volume_mount_point(const rtl::OUString& path)
+{
+ rtl::OUString p(path);
+ osl::systemPathRemoveSeparator(p);
+
+ bool is_volume_root = false;
+
+ if (!is_floppy_drive(p))
+ {
+ DWORD fattr = GetFileAttributes(reinterpret_cast<LPCTSTR>(p.getStr()));
+
+ if ((INVALID_FILE_ATTRIBUTES != fattr) &&
+ (FILE_ATTRIBUTE_REPARSE_POINT & fattr))
+ {
+ WIN32_FIND_DATA find_data;
+ HANDLE h_find = FindFirstFile(reinterpret_cast<LPCTSTR>(p.getStr()), &find_data);
+
+ if (IsValidHandle(h_find) &&
+ (FILE_ATTRIBUTE_REPARSE_POINT & find_data.dwFileAttributes) &&
+ (IO_REPARSE_TAG_MOUNT_POINT == find_data.dwReserved0))
+ {
+ is_volume_root = true;
+ }
+ if (IsValidHandle(h_find))
+ FindClose(h_find);
+ }
+ }
+ return is_volume_root;
+}
+
+//#############################################
+static UINT get_volume_mount_point_drive_type(const rtl::OUString& path)
+{
+ if (0 == path.getLength())
+ return GetDriveType(NULL);
+
+ rtl::OUString p(path);
+ osl::systemPathEnsureSeparator(p);
+
+ TCHAR vn[51];
+ if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
+ return GetDriveType(vn);
+
+ return DRIVE_NO_ROOT_DIR;
+}
+
+//#############################################
+static inline bool is_drivetype_request(sal_uInt32 field_mask)
+{
+ return (field_mask & osl_VolumeInfo_Mask_Attributes);
+}
+
+//#############################################
+static oslFileError osl_get_drive_type(
+ const rtl::OUString& path, oslVolumeInfo* pInfo)
+{
+ // GetDriveType fails on empty volume mount points
+ // see Knowledge Base Q244089
+ UINT drive_type;
+ if (is_volume_mount_point(path))
+ drive_type = get_volume_mount_point_drive_type(path);
+ else
+ drive_type = GetDriveType(reinterpret_cast<LPCTSTR>(path.getStr()));
+
+ if (DRIVE_NO_ROOT_DIR == drive_type)
+ return oslTranslateFileError(ERROR_INVALID_DRIVE);
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+
+ switch (drive_type)
+ {
+ case DRIVE_CDROM:
+ pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
+ break;
+ case DRIVE_REMOVABLE:
+ pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
+ if (is_floppy_drive(path))
+ pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
+ break;
+ case DRIVE_FIXED:
+ pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
+ break;
+ case DRIVE_RAMDISK:
+ pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
+ break;
+ case DRIVE_REMOTE:
+ pInfo->uAttributes |= osl_Volume_Attribute_Remote;
+ break;
+ case DRIVE_UNKNOWN:
+ pInfo->uAttributes = 0;
+ break;
+ default:
+ pInfo->uValidFields &= ~osl_VolumeInfo_Mask_Attributes;
+ pInfo->uAttributes = 0;
+ break;
+ }
+ return osl_File_E_None;
+}
+
+//#############################################
+static inline bool is_volume_space_info_request(sal_uInt32 field_mask)
+{
+ return (field_mask &
+ (osl_VolumeInfo_Mask_TotalSpace |
+ osl_VolumeInfo_Mask_UsedSpace |
+ osl_VolumeInfo_Mask_FreeSpace));
+}
+
+//#############################################
+static void get_volume_space_information(
+ const rtl::OUString& path, oslVolumeInfo *pInfo)
+{
+ BOOL ret = GetDiskFreeSpaceEx(
+ reinterpret_cast<LPCTSTR>(path.getStr()),
+ (PULARGE_INTEGER)&(pInfo->uFreeSpace),
+ (PULARGE_INTEGER)&(pInfo->uTotalSpace),
+ NULL);
+
+ if (ret)
+ {
+ pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace |
+ osl_VolumeInfo_Mask_UsedSpace |
+ osl_VolumeInfo_Mask_FreeSpace;
+ }
+}
+
+//#############################################
+static inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
+{
+ return (field_mask &
+ (osl_VolumeInfo_Mask_MaxNameLength |
+ osl_VolumeInfo_Mask_MaxPathLength |
+ osl_VolumeInfo_Mask_FileSystemName |
+ osl_VolumeInfo_Mask_FileSystemCaseHandling));
+}
+
+//#############################################
+static oslFileError get_filesystem_attributes(
+ const rtl::OUString& path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
+{
+ pInfo->uAttributes = 0;
+
+ // osl_get_drive_type must be called first because
+ // this function resets osl_VolumeInfo_Mask_Attributes
+ // on failure
+ if (is_drivetype_request(field_mask))
+ {
+ oslFileError osl_error = osl_get_drive_type(path, pInfo);
+ if (osl_File_E_None != osl_error)
+ return osl_error;
+ }
+ if (is_filesystem_attributes_request(field_mask))
+ {
+ WCHAR vn[MAX_PATH];
+ WCHAR fsn[MAX_PATH];
+ DWORD serial;
+ DWORD mcl;
+ DWORD flags;
+
+ LPCTSTR pszPath = reinterpret_cast<LPCTSTR>(path.getStr());
+ if (GetVolumeInformation(pszPath, vn, MAX_PATH, &serial, &mcl, &flags, fsn, MAX_PATH))
+ {
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
+ pInfo->uMaxNameLength = mcl;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
+ pInfo->uMaxPathLength = MAX_PATH;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
+ rtl_uString_newFromStr(&pInfo->ustrFileSystemName, reinterpret_cast<const sal_Unicode*>(fsn));
+
+ // volumes (even NTFS) will always be considered case
+ // insensitive because the Win32 API is not able to
+ // deal with case sensitive volumes see M$ Knowledge Base
+ // article 100625 that's why we never set the attribute
+ // osl_Volume_Attribute_Case_Sensitive
+
+ if (flags & FS_CASE_IS_PRESERVED)
+ pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+ }
+ return osl_File_E_None;
+}
+
+//#####################################################
+static bool path_get_parent(rtl::OUString& path)
+{
+ OSL_PRECOND(path.lastIndexOf(SLASH) == -1, "Path must not have slashes");
+
+ if (!has_path_parent(path))
+ {
+ sal_Int32 i = path.lastIndexOf(BACKSLASH);
+ if (-1 < i)
+ {
+ path = rtl::OUString(path.getStr(), i);
+ return true;
+ }
+ }
+ return false;
+}
+
+//#####################################################
+static void path_travel_to_volume_root(const rtl::OUString& system_path, rtl::OUString& volume_root)
+{
+ rtl::OUString sys_path(system_path);
+
+ while(!is_volume_mount_point(sys_path) && path_get_parent(sys_path))
+ /**/;
+
+ volume_root = sys_path;
+ osl::systemPathEnsureSeparator(volume_root);
+}
+
+//#############################################
+oslFileError SAL_CALL osl_getVolumeInformation(
+ rtl_uString *ustrURL, oslVolumeInfo *pInfo, sal_uInt32 uFieldMask )
+{
+ if (!pInfo)
+ return osl_File_E_INVAL;
+
+ rtl::OUString system_path;
+ oslFileError error = _osl_getSystemPathFromFileURL(ustrURL, &system_path.pData, sal_False);
+
+ if (osl_File_E_None != error)
+ return error;
+
+ rtl::OUString volume_root;
+ path_travel_to_volume_root(system_path, volume_root);
+
+ pInfo->uValidFields = 0;
+
+ if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
+ return error;
+
+ if (is_volume_space_info_request(uFieldMask))
+ get_volume_space_information(volume_root, pInfo);
+
+ if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
+ {
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
+ osl_getFileURLFromSystemPath(volume_root.pData, (rtl_uString**)&pInfo->pDeviceHandle);
+ }
+
+ return osl_File_E_None;
+}
+
+//#####################################################
+static oslFileError SAL_CALL osl_getDriveInfo(
+ oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
+{
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+ TCHAR cDrive[3] = TEXT("A:");
+ TCHAR cRoot[4] = TEXT("A:\\");
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ pStatus->uValidFields = 0;
+
+ cDrive[0] = pItemImpl->cDriveString[0];
+ cRoot[0] = pItemImpl->cDriveString[0];
+
+ if ( uFieldMask & osl_FileStatus_Mask_FileName )
+ {
+ if ( pItemImpl->cDriveString[0] == '\\' && pItemImpl->cDriveString[1] == '\\' )
+ {
+ LPCWSTR lpFirstBkSlash = wcschr( &pItemImpl->cDriveString[2], '\\' );
+
+ if ( lpFirstBkSlash && lpFirstBkSlash[1] )
+ {
+ LPCWSTR lpLastBkSlash = wcschr( &lpFirstBkSlash[1], '\\' );
+
+ if ( lpLastBkSlash )
+ rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]), lpLastBkSlash - lpFirstBkSlash - 1 );
+ else
+ rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]) );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+ }
+ }
+ else switch ( GetDriveType( cRoot ) )
+ {
+ case DRIVE_REMOTE:
+ {
+ TCHAR szBuffer[1024];
+ DWORD const dwBufsizeConst = ELEMENTS_OF_ARRAY(szBuffer);
+ DWORD dwBufsize = dwBufsizeConst;
+
+ DWORD dwResult = WNetGetConnection( cDrive, szBuffer, &dwBufsize );
+ if ( NO_ERROR == dwResult )
+ {
+ TCHAR szFileName[dwBufsizeConst + 16];
+
+ swprintf( szFileName, L"%s [%s]", cDrive, szBuffer );
+ rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
+ }
+ else
+ rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
+ }
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+ break;
+ case DRIVE_FIXED:
+ {
+ TCHAR szVolumeNameBuffer[1024];
+ DWORD const dwBufsizeConst = ELEMENTS_OF_ARRAY(szVolumeNameBuffer);
+
+ if ( GetVolumeInformation( cRoot, szVolumeNameBuffer, dwBufsizeConst, NULL, NULL, NULL, NULL, 0 ) )
+ {
+ TCHAR szFileName[dwBufsizeConst + 16];
+
+ swprintf( szFileName, L"%s [%s]", cDrive, szVolumeNameBuffer );
+ rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
+ }
+ else
+ rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
+ }
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+ break;
+ case DRIVE_CDROM:
+ case DRIVE_REMOVABLE:
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+ rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cRoot) );
+ break;
+ case DRIVE_UNKNOWN:
+ default:
+ break;
+ }
+ }
+
+ pStatus->eType = osl_File_Type_Volume;
+ pStatus->uValidFields |= osl_FileStatus_Mask_Type;
+
+ if ( uFieldMask & osl_FileStatus_Mask_FileURL )
+ {
+ rtl_uString *ustrSystemPath = NULL;
+
+ rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->cDriveString) );
+ osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
+ rtl_uString_release( ustrSystemPath );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
+ }
+ return osl_File_E_None;
+}
+
+//#####################################################
+static oslFileError SAL_CALL osl_getServerInfo(
+ oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask )
+{
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ pStatus->uValidFields = 0;
+
+ // pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+
+ // if ( _tcscmp( pItemImpl->FindData.cFileName, TEXT(".") ) == 0 )
+ // rtl_uString_newFromAscii( &pStatus->ustrFileName, "/" );
+ // else
+ // rtl_uString_newFromStr( &pStatus->ustrFileName, pItemImpl->FindData.cFileName );
+
+ pStatus->eType = osl_File_Type_Directory;
+ pStatus->uValidFields |= osl_FileStatus_Mask_Type;
+
+ if ( uFieldMask & osl_FileStatus_Mask_FileURL )
+ {
+ rtl_uString *ustrSystemPath = NULL;
+
+ rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) );
+ osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
+ rtl_uString_release( ustrSystemPath );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
+ }
+ return osl_File_E_None;
+}
+
+//#############################################
+oslFileError SAL_CALL osl_getFileStatus(
+ oslDirectoryItem Item,
+ oslFileStatus *pStatus,
+ sal_uInt32 uFieldMask )
+{
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ switch ( pItemImpl->uType )
+ {
+ case DIRECTORYITEM_DRIVE:
+ return osl_getDriveInfo( Item, pStatus, uFieldMask );
+ case DIRECTORYITEM_SERVER:
+ return osl_getServerInfo( Item, pStatus, uFieldMask );
+ default:
+ break;
+ }
+
+ if ( uFieldMask & osl_FileStatus_Mask_Validate )
+ {
+ HANDLE hFind = FindFirstFile( pItemImpl->szFullPath, &pItemImpl->FindData );
+
+ if ( hFind != INVALID_HANDLE_VALUE )
+ FindClose( hFind );
+ else
+ return oslTranslateFileError( GetLastError() );
+
+ uFieldMask &= ~ osl_FileStatus_Mask_Validate;
+ }
+
+ /* If no fields to retrieve left ignore pStatus */
+ if ( !uFieldMask )
+ return osl_File_E_None;
+
+ /* Otherwise, this must be a valid pointer */
+ if ( !pStatus )
+ return osl_File_E_INVAL;
+
+ if ( pStatus->uStructSize != sizeof(oslFileStatus) )
+ return osl_File_E_INVAL;
+
+ pStatus->uValidFields = 0;
+
+ /* File time stamps */
+
+ if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime) &&
+ FileTimeToTimeValue( &pItemImpl->FindData.ftLastWriteTime, &pStatus->aModifyTime ) )
+ pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;
+
+ if ( (uFieldMask & osl_FileStatus_Mask_AccessTime) &&
+ FileTimeToTimeValue( &pItemImpl->FindData.ftLastAccessTime, &pStatus->aAccessTime ) )
+ pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;
+
+ if ( (uFieldMask & osl_FileStatus_Mask_CreationTime) &&
+ FileTimeToTimeValue( &pItemImpl->FindData.ftCreationTime, &pStatus->aCreationTime ) )
+ pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;
+
+ /* Most of the fields are already set, regardless of requiered fields */
+
+ rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(pItemImpl->FindData.cFileName) );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+
+ if ((FILE_ATTRIBUTE_REPARSE_POINT & pItemImpl->FindData.dwFileAttributes) &&
+ (IO_REPARSE_TAG_MOUNT_POINT == pItemImpl->FindData.dwReserved0))
+ pStatus->eType = osl_File_Type_Volume;
+ else if (pItemImpl->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ pStatus->eType = osl_File_Type_Directory;
+ else
+ pStatus->eType = osl_File_Type_Regular;
+
+ pStatus->uValidFields |= osl_FileStatus_Mask_Type;
+
+ pStatus->uAttributes = pItemImpl->FindData.dwFileAttributes;
+ pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;
+
+ pStatus->uFileSize = (sal_uInt64)pItemImpl->FindData.nFileSizeLow + ((sal_uInt64)pItemImpl->FindData.nFileSizeHigh << 32);
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;
+
+ if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
+ {
+ rtl_uString *ustrFullPath = NULL;
+
+ rtl_uString_newFromStr( &ustrFullPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) );
+ osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrLinkTargetURL );
+ rtl_uString_release( ustrFullPath );
+
+ pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
+ }
+
+ if ( uFieldMask & osl_FileStatus_Mask_FileURL )
+ {
+ rtl_uString *ustrFullPath = NULL;
+
+
+ if ( !pItemImpl->bFullPathNormalized )
+ {
+ GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );
+ pItemImpl->bFullPathNormalized = TRUE;
+ }
+ rtl_uString_newFromStr( &ustrFullPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) );
+ osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL );
+ rtl_uString_release( ustrFullPath );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
+ }
+
+ return osl_File_E_None;
+}
+
+//#####################################################
+// file attributes handling functions
+//#####################################################
+
+//#############################################
+oslFileError SAL_CALL osl_setFileAttributes(
+ rtl_uString *ustrFileURL,
+ sal_uInt64 uAttributes )
+{
+ oslFileError error;
+ rtl_uString *ustrSysPath = NULL;
+ DWORD dwFileAttributes;
+ BOOL fSuccess;
+
+ // Converts the normalized path into a systempath
+ error = _osl_getSystemPathFromFileURL( ustrFileURL, &ustrSysPath, sal_False );
+
+ if ( osl_File_E_None != error )
+ return error;
+
+ dwFileAttributes = GetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)) );
+
+ if ( (DWORD)-1 != dwFileAttributes )
+ {
+ dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN);
+
+ if ( uAttributes & osl_File_Attribute_ReadOnly )
+ dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
+
+ if ( uAttributes & osl_File_Attribute_Hidden )
+ dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
+
+ fSuccess = SetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)), dwFileAttributes );
+ }
+ else
+ fSuccess = FALSE;
+
+ if ( !fSuccess )
+ error = oslTranslateFileError( GetLastError() );
+
+ rtl_uString_release( ustrSysPath );
+
+ return error;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_setFileTime(
+ rtl_uString *filePath,
+ const TimeValue *aCreationTime,
+ const TimeValue *aLastAccessTime,
+ const TimeValue *aLastWriteTime)
+{
+ oslFileError error;
+ rtl_uString *sysPath=NULL;
+ FILETIME *lpCreationTime=NULL;
+ FILETIME *lpLastAccessTime=NULL;
+ FILETIME *lpLastWriteTime=NULL;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ HANDLE hFile;
+ BOOL fSuccess;
+
+
+ error=_osl_getSystemPathFromFileURL(filePath, &sysPath, sal_False);
+
+ if (error==osl_File_E_INVAL)
+ return error;
+
+ hFile=CreateFileW(reinterpret_cast<LPCWSTR>(rtl_uString_getStr(sysPath)), GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ rtl_uString_release(sysPath);
+
+ if (hFile==INVALID_HANDLE_VALUE)
+ return osl_File_E_NOENT;
+
+ if (TimeValueToFileTime(aCreationTime, &ftCreationTime))
+ lpCreationTime=&ftCreationTime;
+
+ if (TimeValueToFileTime(aLastAccessTime, &ftLastAccessTime))
+ lpLastAccessTime=&ftLastAccessTime;
+
+ if (TimeValueToFileTime(aLastWriteTime, &ftLastWriteTime))
+ lpLastWriteTime=&ftLastWriteTime;
+
+ fSuccess=SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
+
+ CloseHandle(hFile);
+
+ if (!fSuccess)
+ return osl_File_E_INVAL;
+ else
+ return osl_File_E_None;
+}
diff --git a/sal/osl/w32/file_error.c b/sal/osl/w32/file_error.c
new file mode 100644
index 000000000..d79bd524b
--- /dev/null
+++ b/sal/osl/w32/file_error.c
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: file_error.c,v $
+ * $Revision: 1.0 $
+ *
+ * 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 "file_error.h"
+
+#include "osl/diagnose.h"
+#include "osl/thread.h"
+
+/* OS error to oslFileError values mapping table */
+struct osl_file_error_entry
+{
+ unsigned long oscode; /* OS return value */
+ int errnocode; /* oslFileError code */
+};
+
+static const struct osl_file_error_entry errtable[] = {
+ { ERROR_SUCCESS, osl_File_E_None }, /* 0 */
+ { ERROR_INVALID_FUNCTION, osl_File_E_INVAL }, /* 1 */
+ { ERROR_FILE_NOT_FOUND, osl_File_E_NOENT }, /* 2 */
+ { ERROR_PATH_NOT_FOUND, osl_File_E_NOENT }, /* 3 */
+ { ERROR_TOO_MANY_OPEN_FILES, osl_File_E_MFILE }, /* 4 */
+ { ERROR_ACCESS_DENIED, osl_File_E_ACCES }, /* 5 */
+ { ERROR_INVALID_HANDLE, osl_File_E_BADF }, /* 6 */
+ { ERROR_ARENA_TRASHED, osl_File_E_NOMEM }, /* 7 */
+ { ERROR_NOT_ENOUGH_MEMORY, osl_File_E_NOMEM }, /* 8 */
+ { ERROR_INVALID_BLOCK, osl_File_E_NOMEM }, /* 9 */
+ { ERROR_BAD_ENVIRONMENT, osl_File_E_2BIG }, /* 10 */
+ { ERROR_BAD_FORMAT, osl_File_E_NOEXEC }, /* 11 */
+ { ERROR_INVALID_ACCESS, osl_File_E_INVAL }, /* 12 */
+ { ERROR_INVALID_DATA, osl_File_E_INVAL }, /* 13 */
+ { ERROR_INVALID_DRIVE, osl_File_E_NOENT }, /* 15 */
+ { ERROR_CURRENT_DIRECTORY, osl_File_E_ACCES }, /* 16 */
+ { ERROR_NOT_SAME_DEVICE, osl_File_E_XDEV }, /* 17 */
+ { ERROR_NO_MORE_FILES, osl_File_E_NOENT }, /* 18 */
+ { ERROR_NOT_READY, osl_File_E_NOTREADY }, /* 21 */
+ { ERROR_LOCK_VIOLATION, osl_File_E_ACCES }, /* 33 */
+ { ERROR_BAD_NETPATH, osl_File_E_NOENT }, /* 53 */
+ { ERROR_NETWORK_ACCESS_DENIED, osl_File_E_ACCES }, /* 65 */
+ { ERROR_BAD_NET_NAME, osl_File_E_NOENT }, /* 67 */
+ { ERROR_FILE_EXISTS, osl_File_E_EXIST }, /* 80 */
+ { ERROR_CANNOT_MAKE, osl_File_E_ACCES }, /* 82 */
+ { ERROR_FAIL_I24, osl_File_E_ACCES }, /* 83 */
+ { ERROR_INVALID_PARAMETER, osl_File_E_INVAL }, /* 87 */
+ { ERROR_NO_PROC_SLOTS, osl_File_E_AGAIN }, /* 89 */
+ { ERROR_DRIVE_LOCKED, osl_File_E_ACCES }, /* 108 */
+ { ERROR_BROKEN_PIPE, osl_File_E_PIPE }, /* 109 */
+ { ERROR_DISK_FULL, osl_File_E_NOSPC }, /* 112 */
+ { ERROR_INVALID_TARGET_HANDLE, osl_File_E_BADF }, /* 114 */
+ { ERROR_INVALID_HANDLE, osl_File_E_INVAL }, /* 124 */
+ { ERROR_WAIT_NO_CHILDREN, osl_File_E_CHILD }, /* 128 */
+ { ERROR_CHILD_NOT_COMPLETE, osl_File_E_CHILD }, /* 129 */
+ { ERROR_DIRECT_ACCESS_HANDLE, osl_File_E_BADF }, /* 130 */
+ { ERROR_NEGATIVE_SEEK, osl_File_E_INVAL }, /* 131 */
+ { ERROR_SEEK_ON_DEVICE, osl_File_E_ACCES }, /* 132 */
+ { ERROR_DIR_NOT_EMPTY, osl_File_E_NOTEMPTY }, /* 145 */
+ { ERROR_NOT_LOCKED, osl_File_E_ACCES }, /* 158 */
+ { ERROR_BAD_PATHNAME, osl_File_E_NOENT }, /* 161 */
+ { ERROR_MAX_THRDS_REACHED, osl_File_E_AGAIN }, /* 164 */
+ { ERROR_LOCK_FAILED, osl_File_E_ACCES }, /* 167 */
+ { ERROR_ALREADY_EXISTS, osl_File_E_EXIST }, /* 183 */
+ { ERROR_FILENAME_EXCED_RANGE, osl_File_E_NOENT }, /* 206 */
+ { ERROR_NESTING_NOT_ALLOWED, osl_File_E_AGAIN }, /* 215 */
+ { ERROR_DIRECTORY, osl_File_E_NOENT }, /* 267 */
+ { ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM }, /* 1816 */
+ { ERROR_UNEXP_NET_ERR, osl_File_E_NETWORK } /* 59 */
+};
+
+/* The following two constants must be the minimum and maximum
+ values in the (contiguous) range of osl_File_E_xec Failure errors.
+*/
+#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
+#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
+
+/* These are the low and high value in the range of errors that are
+ access violations
+*/
+#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
+#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
+
+oslFileError oslTranslateFileError (/*DWORD*/ unsigned long dwError)
+{
+ static const int n = sizeof(errtable)/sizeof(errtable[0]);
+
+ int i;
+ for (i = 0; i < n; ++i )
+ {
+ if (dwError == errtable[i].oscode)
+ return (oslFileError)(errtable[i].errnocode);
+ }
+
+ /* The error code wasn't in the table. We check for a range of
+ osl_File_E_ACCES errors or exec failure errors (ENOEXEC).
+ Otherwise osl_File_E_INVAL is returned.
+ */
+ if ( (dwError >= MIN_EACCES_RANGE) && (dwError <= MAX_EACCES_RANGE) )
+ return osl_File_E_ACCES;
+ else if ( (dwError >= MIN_EXEC_ERROR) && (dwError <= MAX_EXEC_ERROR) )
+ return osl_File_E_NOEXEC;
+ else
+ return osl_File_E_INVAL;
+}
+
+//#####################################################
+#if OSL_DEBUG_LEVEL > 0
+void _osl_warnFile( const char *message, rtl_uString *ustrFile )
+{
+ char szBuffer[2048];
+
+ if (ustrFile)
+ {
+ rtl_String *strFile = NULL;
+
+ rtl_uString2String( &strFile, rtl_uString_getStr( ustrFile ), rtl_uString_getLength( ustrFile ),
+ osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
+ snprintf( szBuffer, sizeof(szBuffer), message, strFile->buffer );
+ rtl_string_release( strFile );
+
+ message = szBuffer;
+ }
+ OSL_ENSURE( 0, message );
+}
+#endif /* OSL_DEBUG_LEVEL */
diff --git a/sal/osl/w32/file_error.h b/sal/osl/w32/file_error.h
new file mode 100644
index 000000000..c59e513f0
--- /dev/null
+++ b/sal/osl/w32/file_error.h
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: file_error.h,v $
+ * $Revision: 1.0 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_OSL_FILE_ERROR_H
+#define INCLUDED_OSL_FILE_ERROR_H
+
+#include "osl/file.h"
+#include "rtl/ustring.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+oslFileError oslTranslateFileError (/*DWORD*/ unsigned long dwError);
+
+#if OSL_DEBUG_LEVEL > 0
+void _osl_warnFile (const char * message, rtl_uString * ustrFile);
+#define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ? (void)0 : _osl_warnFile( msg, file ) )
+#else
+#define OSL_ENSURE_FILE( cond, msg, file ) ((void)0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_OSL_FILE_ERROR_H */
diff --git a/sal/osl/w32/file_url.cxx b/sal/osl/w32/file_url.cxx
new file mode 100644
index 000000000..d4fc62c07
--- /dev/null
+++ b/sal/osl/w32/file_url.cxx
@@ -0,0 +1,1013 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: file_url.cxx,v $
+ * $Revision: 1.0 $
+ *
+ * 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 "file_url.h"
+#include "file_error.h"
+
+#include "rtl/alloc.h"
+#include "osl/diagnose.h"
+#include "osl/file.h"
+#include "osl/mutex.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+#if OSL_DEBUG_LEVEL > 0
+#define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ? (void)0 : _osl_warnFile( msg, file ) )
+#else
+#define OSL_ENSURE_FILE( cond, msg, file ) ((void)0)
+#endif
+
+#define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
+
+//##################################################################
+// FileURL functions
+//##################################################################
+
+extern "C" oslMutex g_CurrentDirectoryMutex; /* Initialized in dllentry.c */
+oslMutex g_CurrentDirectoryMutex = 0;
+
+//#####################################################
+static BOOL IsValidFilePathComponent(
+ LPCTSTR lpComponent, LPCTSTR *lppComponentEnd, DWORD dwFlags)
+{
+ LPCTSTR lpComponentEnd = NULL;
+ LPCTSTR lpCurrent = lpComponent;
+ BOOL fValid = TRUE; /* Assume success */
+ TCHAR cLast = 0;
+
+ /* Path component length must not exceed MAX_PATH */
+
+ while ( !lpComponentEnd && lpCurrent && lpCurrent - lpComponent < MAX_PATH )
+ {
+ switch ( *lpCurrent )
+ {
+ /* Both backslash and slash determine the end of a path component */
+ case '\0':
+ case '/':
+ case '\\':
+ switch ( cLast )
+ {
+ /* Component must not end with '.' or blank and can't be empty */
+
+ case '.':
+ if ( dwFlags & VALIDATEPATH_ALLOW_ELLIPSE )
+ {
+ if ( 1 == lpCurrent - lpComponent )
+ {
+ /* Current directory is O.K. */
+ lpComponentEnd = lpCurrent;
+ break;
+ }
+ else if ( 2 == lpCurrent - lpComponent && '.' == *lpComponent )
+ {
+ /* Parent directory is O.K. */
+ lpComponentEnd = lpCurrent;
+ break;
+ }
+ }
+ case 0:
+ case ' ':
+ lpComponentEnd = lpCurrent - 1;
+ fValid = FALSE;
+ break;
+ default:
+ lpComponentEnd = lpCurrent;
+ break;
+ }
+ break;
+ /* '?' and '*' are valid wildcards but not valid file name characters */
+ case '?':
+ case '*':
+ if ( dwFlags & VALIDATEPATH_ALLOW_WILDCARDS )
+ break;
+ /* The following characters are reserved */
+ case '<':
+ case '>':
+ case '\"':
+ case '|':
+ case ':':
+ lpComponentEnd = lpCurrent;
+ fValid = FALSE;
+ break;
+ default:
+ /* Characters below ASCII 32 are not allowed */
+ if ( *lpCurrent < ' ' )
+ {
+ lpComponentEnd = lpCurrent;
+ fValid = FALSE;
+ }
+ break;
+ }
+ cLast = *lpCurrent++;
+ }
+
+ /* If we don't reached the end of the component the length of the component was to long
+ ( See condition of while loop ) */
+ if ( !lpComponentEnd )
+ {
+ fValid = FALSE;
+ lpComponentEnd = lpCurrent;
+ }
+
+ /* Test wether the component specifies a device name what is not allowed */
+
+ // MT: PERFORMANCE:
+ // This is very expensive. A lot of calls to _tcsicmp.
+ // in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp!
+ // Possible optimizations
+ // - Array should be const static
+ // - Sorted array, use binary search
+ // - More intelligent check for com1-9, lpt1-9
+ // Maybe make szComponent upper case, don't search case intensitive
+ // Talked to HRO: Could be removed. Shouldn't be used in OOo, and if used for something like a filename, it will lead to an error anyway.
+ /*
+ if ( fValid )
+ {
+ LPCTSTR alpDeviceNames[] =
+ {
+ TEXT("CON"),
+ TEXT("PRN"),
+ TEXT("AUX"),
+ TEXT("CLOCK$"),
+ TEXT("NUL"),
+ TEXT("LPT1"),
+ TEXT("LPT2"),
+ TEXT("LPT3"),
+ TEXT("LPT4"),
+ TEXT("LPT5"),
+ TEXT("LPT6"),
+ TEXT("LPT7"),
+ TEXT("LPT8"),
+ TEXT("LPT9"),
+ TEXT("COM1"),
+ TEXT("COM2"),
+ TEXT("COM3"),
+ TEXT("COM4"),
+ TEXT("COM5"),
+ TEXT("COM6"),
+ TEXT("COM7"),
+ TEXT("COM8"),
+ TEXT("COM9")
+ };
+
+ TCHAR szComponent[MAX_PATH];
+ int nComponentLength;
+ LPCTSTR lpDot;
+ int i;
+
+ // A device name with an extension is also invalid
+ lpDot = _tcschr( lpComponent, '.' );
+
+ if ( !lpDot || lpDot > lpComponentEnd )
+ nComponentLength = lpComponentEnd - lpComponent;
+ else
+ nComponentLength = lpDot - lpComponent;
+
+ _tcsncpy( szComponent, lpComponent, nComponentLength );
+ szComponent[nComponentLength] = 0;
+
+ for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ )
+ {
+ if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) )
+ {
+ lpComponentEnd = lpComponent;
+ fValid = FALSE;
+ break;
+ }
+ }
+ }
+ */
+
+ if ( fValid )
+ {
+ // Empty components are not allowed
+ if ( lpComponentEnd - lpComponent < 1 )
+ fValid = FALSE;
+
+ // If we reached the end of the string NULL is returned
+ else if ( !*lpComponentEnd )
+ lpComponentEnd = NULL;
+
+ }
+
+ if ( lppComponentEnd )
+ *lppComponentEnd = lpComponentEnd;
+
+ return fValid;
+}
+
+//#####################################################
+#define CHARSET_SEPARATOR TEXT("\\/")
+
+DWORD IsValidFilePath(rtl_uString *path, LPCTSTR *lppError, DWORD dwFlags, rtl_uString **corrected)
+{
+ LPCTSTR lpszPath = reinterpret_cast< LPCTSTR >(path->buffer);
+ LPCTSTR lpComponent;
+ BOOL fValid = TRUE;
+ DWORD dwPathType = PATHTYPE_ERROR;
+
+ if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
+ dwFlags |= VALIDATEPATH_ALLOW_ELLIPSE;
+
+ if ( !lpszPath )
+ {
+ fValid = FALSE;
+ lpComponent = lpszPath;
+ }
+
+ /* Test for UNC path notation */
+ if ( 2 == _tcsspn( lpszPath, CHARSET_SEPARATOR ) )
+ {
+ /* Place the pointer behind the leading to backslashes */
+
+ lpComponent = lpszPath + 2;
+
+ fValid = IsValidFilePathComponent( lpComponent, &lpComponent, VALIDATEPATH_ALLOW_ELLIPSE );
+
+ /* So far we have a valid servername. Now let's see if we also have a network resource */
+
+ dwPathType = PATHTYPE_ABSOLUTE_UNC;
+
+ if ( fValid )
+ {
+ if ( lpComponent && !*++lpComponent )
+ lpComponent = NULL;
+
+ if ( !lpComponent )
+ {
+ #if 0
+ /* We only have a Server specification what is invalid */
+
+ lpComponent = lpszPath;
+ fValid = FALSE;
+ #else
+ dwPathType |= PATHTYPE_IS_SERVER;
+ #endif
+ }
+ else
+ {
+ /* Now test the network resource */
+
+ fValid = IsValidFilePathComponent( lpComponent, &lpComponent, 0 );
+
+ /* If we now reached the end of the path, everything is O.K. */
+
+
+ if ( fValid && (!lpComponent || lpComponent && !*++lpComponent ) )
+ {
+ lpComponent = NULL;
+ dwPathType |= PATHTYPE_IS_VOLUME;
+ }
+ }
+ }
+ }
+
+ /* Local path verification. Must start with <drive>: */
+ else if ( _istalpha( lpszPath[0] ) && ':' == lpszPath[1] )
+ {
+ /* Place pointer behind correct drive specification */
+
+ lpComponent = lpszPath + 2;
+
+ if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
+ lpComponent++;
+ else if ( *lpComponent )
+ fValid = FALSE;
+
+ dwPathType = PATHTYPE_ABSOLUTE_LOCAL;
+
+ /* Now we are behind the backslash or it was a simple drive without backslash */
+
+ if ( fValid && !*lpComponent )
+ {
+ lpComponent = NULL;
+ dwPathType |= PATHTYPE_IS_VOLUME;
+ }
+ }
+
+ /* Can be a relative path */
+ else if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
+ {
+ lpComponent = lpszPath;
+
+ /* Relative path can start with a backslash */
+
+ if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
+ {
+ lpComponent++;
+ if ( !*lpComponent )
+ lpComponent = NULL;
+ }
+
+ dwPathType = PATHTYPE_RELATIVE;
+ }
+
+ /* Anything else is an error */
+ else
+ {
+ fValid = FALSE;
+ lpComponent = lpszPath;
+ }
+
+ /* Now validate each component of the path */
+ while ( fValid && lpComponent )
+ {
+ // Correct path by merging consecutive slashes:
+ if (*lpComponent == '\\' && corrected != NULL) {
+ sal_Int32 i = lpComponent - lpszPath;
+ rtl_uString_newReplaceStrAt(corrected, path, i, 1, NULL);
+ //TODO: handle out-of-memory
+ lpszPath = reinterpret_cast< LPCTSTR >((*corrected)->buffer);
+ lpComponent = lpszPath + i;
+ }
+
+ fValid = IsValidFilePathComponent( lpComponent, &lpComponent, dwFlags );
+
+ if ( fValid && lpComponent )
+ {
+ lpComponent++;
+
+ /* If the string behind the backslash is empty, we've done */
+
+ if ( !*lpComponent )
+ lpComponent = NULL;
+ }
+ }
+
+ if ( fValid && _tcslen( lpszPath ) >= MAX_PATH )
+ {
+ fValid = FALSE;
+ lpComponent = lpszPath + MAX_PATH;
+ }
+
+ if ( lppError )
+ *lppError = lpComponent;
+
+ return fValid ? dwPathType : PATHTYPE_ERROR;
+}
+
+//#############################################
+//#####################################################
+//Undocumented in SHELL32.DLL ordinal 35
+static BOOL PathRemoveFileSpec(LPTSTR lpPath)
+{
+ BOOL fSuccess = FALSE; // Assume failure
+ LPTSTR lpLastBkSlash = _tcsrchr( lpPath, '\\' );
+ LPTSTR lpLastSlash = _tcsrchr( lpPath, '/' );
+ LPTSTR lpLastDelimiter = lpLastSlash > lpLastBkSlash ? lpLastSlash : lpLastBkSlash;
+
+ if ( lpLastDelimiter )
+ {
+ if ( 0 == *(lpLastDelimiter + 1) )
+ {
+ if ( lpLastDelimiter > lpPath && *(lpLastDelimiter - 1) != ':' )
+ {
+ *lpLastDelimiter = 0;
+ fSuccess = TRUE;
+ }
+ }
+ else
+ {
+ *(++lpLastDelimiter) = 0;
+ fSuccess = TRUE;
+ }
+ }
+ return fSuccess;
+}
+
+//#####################################################
+// Undocumented in SHELL32.DLL ordinal 32
+static LPTSTR PathAddBackslash(LPTSTR lpPath)
+{
+ LPTSTR lpEndPath = NULL;
+
+ if ( lpPath )
+ {
+ int nLen = _tcslen(lpPath);
+
+ if ( !nLen || lpPath[nLen-1] != '\\' && lpPath[nLen-1] != '/' && nLen < MAX_PATH - 1 )
+ {
+ lpEndPath = lpPath + nLen;
+ *lpEndPath++ = '\\';
+ *lpEndPath = 0;
+ }
+ }
+ return lpEndPath;
+}
+
+//#####################################################
+// Same as GetLongPathName but also 95/NT4
+static DWORD GetCaseCorrectPathNameEx(
+ LPCTSTR lpszShortPath, // file name
+ LPTSTR lpszLongPath, // path buffer
+ DWORD cchBuffer, // size of path buffer
+ DWORD nSkipLevels
+)
+{
+ TCHAR szPath[MAX_PATH];
+ BOOL fSuccess;
+
+ cchBuffer = cchBuffer; /* avoid warnings */
+
+ _tcscpy( szPath, lpszShortPath );
+
+ fSuccess = PathRemoveFileSpec( szPath );
+
+ if ( fSuccess )
+ {
+ int nLen = _tcslen( szPath );
+ LPCTSTR lpszFileSpec = lpszShortPath + nLen;
+ BOOL bSkipThis;
+
+ if ( 0 == _tcscmp( lpszFileSpec, TEXT("..") ) )
+ {
+ bSkipThis = TRUE;
+ nSkipLevels += 1;
+ }
+ else if (
+ 0 == _tcscmp( lpszFileSpec, TEXT(".") ) ||
+ 0 == _tcscmp( lpszFileSpec, TEXT("\\") ) ||
+ 0 == _tcscmp( lpszFileSpec, TEXT("/") )
+ )
+ {
+ bSkipThis = TRUE;
+ }
+ else if ( nSkipLevels )
+ {
+ bSkipThis = TRUE;
+ nSkipLevels--;
+ }
+ else
+ bSkipThis = FALSE;
+
+ GetCaseCorrectPathNameEx( szPath, szPath, MAX_PATH, nSkipLevels );
+
+ PathAddBackslash( szPath );
+
+ /* Analyze parent if not only a trailing backslash was cutted but a real file spec */
+ if ( !bSkipThis )
+ {
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( lpszShortPath, &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ _tcscat( szPath, aFindFileData.cFileName[0] ? aFindFileData.cFileName : aFindFileData.cAlternateFileName );
+
+ FindClose( hFind );
+ }
+ else
+ return 0;
+ }
+ }
+ else
+ {
+ /* File specification can't be removed therefore the short path is either a drive
+ or a network share. If still levels to skip are left, the path specification
+ tries to travel below the file system root */
+ if ( nSkipLevels )
+ return 0;
+
+ _tcsupr( szPath );
+ }
+
+ _tcscpy( lpszLongPath, szPath );
+
+ return _tcslen( lpszLongPath );
+}
+
+//#####################################################
+#define WSTR_SYSTEM_ROOT_PATH L"\\\\.\\"
+
+DWORD GetCaseCorrectPathName(
+ LPCTSTR lpszShortPath, // file name
+ LPTSTR lpszLongPath, // path buffer
+ DWORD cchBuffer // size of path buffer
+)
+{
+ /* Special handling for "\\.\" as system root */
+ if ( lpszShortPath && 0 == wcscmp( lpszShortPath, WSTR_SYSTEM_ROOT_PATH ) )
+ {
+ if ( cchBuffer >= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) )
+ {
+ wcscpy( lpszLongPath, WSTR_SYSTEM_ROOT_PATH );
+ return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1;
+ }
+ else
+ {
+ return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1;
+ }
+ }
+ else
+ {
+ return GetCaseCorrectPathNameEx( lpszShortPath, lpszLongPath, cchBuffer, 0 );
+ }
+}
+
+//#############################################
+static sal_Bool _osl_decodeURL( rtl_String* strUTF8, rtl_uString** pstrDecodedURL )
+{
+ sal_Char *pBuffer;
+ const sal_Char *pSrcEnd;
+ const sal_Char *pSrc;
+ sal_Char *pDest;
+ sal_Int32 nSrcLen;
+ sal_Bool bValidEncoded = sal_True; /* Assume success */
+
+ /* The resulting decoded string length is shorter or equal to the source length */
+
+ nSrcLen = rtl_string_getLength(strUTF8);
+ pBuffer = reinterpret_cast<sal_Char*>(rtl_allocateMemory(nSrcLen + 1));
+
+ pDest = pBuffer;
+ pSrc = rtl_string_getStr(strUTF8);
+ pSrcEnd = pSrc + nSrcLen;
+
+ /* Now decode the URL what should result in an UTF8 string */
+ while ( bValidEncoded && pSrc < pSrcEnd )
+ {
+ switch ( *pSrc )
+ {
+ case '%':
+ {
+ sal_Char aToken[3];
+ sal_Char aChar;
+
+ pSrc++;
+ aToken[0] = *pSrc++;
+ aToken[1] = *pSrc++;
+ aToken[2] = 0;
+
+ aChar = (sal_Char)strtoul( aToken, NULL, 16 );
+
+ /* The chars are path delimiters and must not be encoded */
+
+ if ( 0 == aChar || '\\' == aChar || '/' == aChar || ':' == aChar )
+ bValidEncoded = sal_False;
+ else
+ *pDest++ = aChar;
+ }
+ break;
+ default:
+ *pDest++ = *pSrc++;
+ break;
+ }
+ }
+
+ *pDest++ = 0;
+
+ if ( bValidEncoded )
+ {
+ rtl_string2UString( pstrDecodedURL, pBuffer, rtl_str_getLength(pBuffer), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
+ OSL_ASSERT(*pstrDecodedURL != 0);
+ }
+
+ rtl_freeMemory( pBuffer );
+
+ return bValidEncoded;
+}
+
+//#############################################
+static void _osl_encodeURL( rtl_uString *strURL, rtl_String **pstrEncodedURL )
+{
+ /* Encode non ascii characters within the URL */
+
+ rtl_String *strUTF8 = NULL;
+ sal_Char *pszEncodedURL;
+ const sal_Char *pURLScan;
+ sal_Char *pURLDest;
+ sal_Int32 nURLScanLen;
+ sal_Int32 nURLScanCount;
+
+ rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
+
+ pszEncodedURL = (sal_Char*) rtl_allocateMemory( (rtl_string_getLength( strUTF8 ) * 3 + 1) * sizeof(sal_Char) );
+
+ pURLDest = pszEncodedURL;
+ pURLScan = rtl_string_getStr( strUTF8 );
+ nURLScanLen = rtl_string_getLength( strUTF8 );
+ nURLScanCount = 0;
+
+ while ( nURLScanCount < nURLScanLen )
+ {
+ sal_Char cCurrent = *pURLScan;
+ switch ( cCurrent )
+ {
+ default:
+ if (!( ( cCurrent >= 'a' && cCurrent <= 'z' ) || ( cCurrent >= 'A' && cCurrent <= 'Z' ) || ( cCurrent >= '0' && cCurrent <= '9' ) ) )
+ {
+ sprintf( pURLDest, "%%%02X", (unsigned char)cCurrent );
+ pURLDest += 3;
+ break;
+ }
+ case '!':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '-':
+ case '.':
+ case '_':
+ case '~':
+ case '$':
+ case '&':
+ case '+':
+ case ',':
+ case '=':
+ case '@':
+ case ':':
+ case '/':
+ case '\\':
+ case '|':
+ *pURLDest++ = cCurrent;
+ break;
+ case 0:
+ break;
+ }
+
+ pURLScan++;
+ nURLScanCount++;
+ }
+
+ *pURLDest = 0;
+
+ rtl_string_release( strUTF8 );
+ rtl_string_newFromStr( pstrEncodedURL, pszEncodedURL );
+ rtl_freeMemory( pszEncodedURL );
+}
+
+//#############################################
+#define WSTR_SYSTEM_ROOT_PATH L"\\\\.\\"
+
+oslFileError _osl_getSystemPathFromFileURL( rtl_uString *strURL, rtl_uString **pustrPath, sal_Bool bAllowRelative )
+{
+ rtl_String *strUTF8 = NULL;
+ rtl_uString *strDecodedURL = NULL;
+ rtl_uString *strTempPath = NULL;
+ const sal_Unicode *pDecodedURL;
+ sal_uInt32 nDecodedLen;
+ sal_Bool bValidEncoded;
+ oslFileError nError = osl_File_E_INVAL; /* Assume failure */
+
+ /* If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from
+ having a mixed encoded URL later */
+
+ rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
+
+ /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */
+
+ OSL_ENSURE_FILE(
+ strUTF8->length == strURL->length ||
+ 0 != rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( strURL->buffer, strURL->length, "file:\\\\", 7 )
+ ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL );
+
+ bValidEncoded = _osl_decodeURL( strUTF8, &strDecodedURL );
+
+ /* Release the encoded UTF8 string */
+ rtl_string_release( strUTF8 );
+
+ if ( bValidEncoded )
+ {
+ /* Replace backslashes and pipes */
+
+ rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '/', '\\' );
+ rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '|', ':' );
+
+ pDecodedURL = rtl_uString_getStr( strDecodedURL );
+ nDecodedLen = rtl_uString_getLength( strDecodedURL );
+
+ /* Must start with "file://" */
+ if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\", 7 ) )
+ {
+ sal_uInt32 nSkip;
+
+ if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\\\", 8 ) )
+ nSkip = 8;
+ else if (
+ 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\localhost\\", 17 ) ||
+ 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\127.0.0.1\\", 17 )
+ )
+ nSkip = 17;
+ else
+ nSkip = 5;
+
+ /* Indicates local root */
+ if ( nDecodedLen == nSkip )
+ rtl_uString_newFromStr_WithLength( &strTempPath, reinterpret_cast<const sal_Unicode*>(WSTR_SYSTEM_ROOT_PATH), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 );
+ else
+ rtl_uString_newFromStr_WithLength( &strTempPath, pDecodedURL + nSkip, nDecodedLen - nSkip );
+
+ if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) )
+ nError = osl_File_E_None;
+ }
+ else if ( bAllowRelative ) /* This maybe a relative file URL */
+ {
+ rtl_uString_assign( &strTempPath, strDecodedURL );
+
+ if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_RELATIVE | VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) )
+ nError = osl_File_E_None;
+ }
+ /*
+ else
+ OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL );
+ */
+
+ }
+
+ if ( strDecodedURL )
+ rtl_uString_release( strDecodedURL );
+
+ if ( osl_File_E_None == nError )
+ rtl_uString_assign( pustrPath, strTempPath );
+
+ if ( strTempPath )
+ rtl_uString_release( strTempPath );
+
+ /*
+ OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL );
+ */
+
+ return nError;
+}
+
+//#############################################
+oslFileError _osl_getFileURLFromSystemPath( rtl_uString* strPath, rtl_uString** pstrURL )
+{
+ oslFileError nError = osl_File_E_INVAL; /* Assume failure */
+ rtl_uString *strTempURL = NULL;
+ DWORD dwPathType = PATHTYPE_ERROR;
+
+ if (strPath)
+ dwPathType = IsValidFilePath(strPath, NULL, VALIDATEPATH_ALLOW_RELATIVE, NULL);
+
+ if (dwPathType)
+ {
+ rtl_uString *strTempPath = NULL;
+
+ /* Replace backslashes */
+ rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' );
+
+ switch ( dwPathType & PATHTYPE_MASK_TYPE )
+ {
+ case PATHTYPE_RELATIVE:
+ rtl_uString_assign( &strTempURL, strTempPath );
+ nError = osl_File_E_None;
+ break;
+ case PATHTYPE_ABSOLUTE_UNC:
+ rtl_uString_newFromAscii( &strTempURL, "file:" );
+ rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
+ nError = osl_File_E_None;
+ break;
+ case PATHTYPE_ABSOLUTE_LOCAL:
+ rtl_uString_newFromAscii( &strTempURL, "file:///" );
+ rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
+ nError = osl_File_E_None;
+ break;
+ default:
+ break;
+ }
+
+ /* Release temp path */
+ rtl_uString_release( strTempPath );
+ }
+
+ if ( osl_File_E_None == nError )
+ {
+ rtl_String *strEncodedURL = NULL;
+
+ /* Encode the URL */
+ _osl_encodeURL( strTempURL, &strEncodedURL );
+
+ /* Provide URL via unicode string */
+ rtl_string2UString( pstrURL, rtl_string_getStr(strEncodedURL), rtl_string_getLength(strEncodedURL), RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
+ OSL_ASSERT(*pstrURL != 0);
+ rtl_string_release( strEncodedURL );
+ }
+
+ /* Release temp URL */
+ if ( strTempURL )
+ rtl_uString_release( strTempURL );
+
+ /*
+ OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath );
+ */
+ return nError;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_getFileURLFromSystemPath(
+ rtl_uString* ustrPath, rtl_uString** pustrURL )
+{
+ return _osl_getFileURLFromSystemPath( ustrPath, pustrURL );
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_getSystemPathFromFileURL(
+ rtl_uString *ustrURL, rtl_uString **pustrPath)
+{
+ return _osl_getSystemPathFromFileURL( ustrURL, pustrPath, sal_True );
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_searchFileURL(
+ rtl_uString *ustrFileName,
+ rtl_uString *ustrSystemSearchPath,
+ rtl_uString **pustrPath)
+{
+ rtl_uString *ustrUNCPath = NULL;
+ rtl_uString *ustrSysPath = NULL;
+ oslFileError error;
+
+ /* First try to interpret the file name as an URL even a relative one */
+ error = _osl_getSystemPathFromFileURL( ustrFileName, &ustrUNCPath, sal_True );
+
+ /* So far we either have an UNC path or something invalid
+ Now create a system path */
+ if ( osl_File_E_None == error )
+ error = _osl_getSystemPathFromFileURL( ustrUNCPath, &ustrSysPath, sal_True );
+
+ if ( osl_File_E_None == error )
+ {
+ DWORD nBufferLength;
+ DWORD dwResult;
+ LPTSTR lpBuffer = NULL;
+ LPTSTR lpszFilePart;
+
+ /* Repeat calling SearchPath ...
+ Start with MAX_PATH for the buffer. In most cases this
+ will be enough and does not force the loop to runtwice */
+ dwResult = MAX_PATH;
+
+ do
+ {
+ /* If search path is empty use a NULL pointer instead according to MSDN documentation of SearchPath */
+ LPCTSTR lpszSearchPath = ustrSystemSearchPath && ustrSystemSearchPath->length ? reinterpret_cast<LPCTSTR>(ustrSystemSearchPath->buffer) : NULL;
+ LPCTSTR lpszSearchFile = reinterpret_cast<LPCTSTR>(ustrSysPath->buffer);
+
+ /* Allocate space for buffer according to previous returned count of required chars */
+ /* +1 is not neccessary if we follow MSDN documentation but for robustness we do so */
+ nBufferLength = dwResult + 1;
+ lpBuffer = lpBuffer ?
+ reinterpret_cast<LPTSTR>(rtl_reallocateMemory(lpBuffer, nBufferLength * sizeof(TCHAR))) :
+ reinterpret_cast<LPTSTR>(rtl_allocateMemory(nBufferLength * sizeof(TCHAR)));
+
+ dwResult = SearchPath( lpszSearchPath, lpszSearchFile, NULL, nBufferLength, lpBuffer, &lpszFilePart );
+ } while ( dwResult && dwResult >= nBufferLength );
+
+ /* ... until an error occures or buffer is large enough.
+ dwResult == nBufferLength can not happen according to documentation but lets be robust ;-) */
+
+ if ( dwResult )
+ {
+ rtl_uString_newFromStr( &ustrSysPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) );
+ error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath );
+ }
+ else
+ {
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind;
+
+ /* Somthing went wrong, perhaps the path was absolute */
+ error = oslTranslateFileError( GetLastError() );
+
+ hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(ustrSysPath->buffer), &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath );
+ FindClose( hFind );
+ }
+ }
+
+ rtl_freeMemory( lpBuffer );
+ }
+
+ if ( ustrSysPath )
+ rtl_uString_release( ustrSysPath );
+
+ if ( ustrUNCPath )
+ rtl_uString_release( ustrUNCPath );
+
+ return error;
+}
+
+//#####################################################
+
+oslFileError SAL_CALL osl_getAbsoluteFileURL( rtl_uString* ustrBaseURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL )
+{
+ oslFileError eError;
+ rtl_uString *ustrRelSysPath = NULL;
+ rtl_uString *ustrBaseSysPath = NULL;
+
+ if ( ustrBaseURL && ustrBaseURL->length )
+ {
+ eError = _osl_getSystemPathFromFileURL( ustrBaseURL, &ustrBaseSysPath, sal_False );
+ OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with relative or invalid base URL" );
+
+ eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_True );
+ }
+ else
+ {
+ eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_False );
+ OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" );
+ }
+
+ if ( !eError )
+ {
+ TCHAR szBuffer[MAX_PATH];
+ TCHAR szCurrentDir[MAX_PATH];
+ LPTSTR lpFilePart = NULL;
+ DWORD dwResult;
+
+/*@@@ToDo
+ Bad, bad hack, this only works if the base path
+ really exists which is not necessary according
+ to RFC2396
+ The whole FileURL implementation should be merged
+ with the rtl/uri class.
+*/
+ if ( ustrBaseSysPath )
+ {
+ osl_acquireMutex( g_CurrentDirectoryMutex );
+
+ GetCurrentDirectory( MAX_PATH, szCurrentDir );
+ SetCurrentDirectory( reinterpret_cast<LPCTSTR>(ustrBaseSysPath->buffer) );
+ }
+
+ dwResult = GetFullPathName( reinterpret_cast<LPCTSTR>(ustrRelSysPath->buffer), MAX_PATH, szBuffer, &lpFilePart );
+
+ if ( ustrBaseSysPath )
+ {
+ SetCurrentDirectory( szCurrentDir );
+
+ osl_releaseMutex( g_CurrentDirectoryMutex );
+ }
+
+ if ( dwResult )
+ {
+ if ( dwResult >= MAX_PATH )
+ eError = osl_File_E_INVAL;
+ else
+ {
+ rtl_uString *ustrAbsSysPath = NULL;
+
+ rtl_uString_newFromStr( &ustrAbsSysPath, reinterpret_cast<const sal_Unicode*>(szBuffer) );
+
+ eError = osl_getFileURLFromSystemPath( ustrAbsSysPath, pustrAbsoluteURL );
+
+ if ( ustrAbsSysPath )
+ rtl_uString_release( ustrAbsSysPath );
+ }
+ }
+ else
+ eError = oslTranslateFileError( GetLastError() );
+ }
+
+ if ( ustrBaseSysPath )
+ rtl_uString_release( ustrBaseSysPath );
+
+ if ( ustrRelSysPath )
+ rtl_uString_release( ustrRelSysPath );
+
+ return eError;
+}
+
+//#####################################################
+oslFileError SAL_CALL osl_getCanonicalName( rtl_uString *strRequested, rtl_uString **strValid )
+{
+ rtl_uString_newFromString(strValid, strRequested);
+ return osl_File_E_None;
+}
diff --git a/sal/osl/w32/file_url.h b/sal/osl/w32/file_url.h
new file mode 100644
index 000000000..c84dee255
--- /dev/null
+++ b/sal/osl/w32/file_url.h
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: file_url.h,v $
+ * $Revision: 1.0 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_OSL_FILE_URL_H
+#define INCLUDED_OSL_FILE_URL_H
+
+#include "sal/types.h"
+#include "rtl/ustring.h"
+#include "osl/file.h"
+
+#ifdef _MSC_VER
+#pragma warning(push,1)
+#endif
+
+#define WINDOWS_LEAN_AND_MEAN
+#include <windows.h>
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PATHTYPE_ERROR 0
+#define PATHTYPE_RELATIVE 1
+#define PATHTYPE_ABSOLUTE_UNC 2
+#define PATHTYPE_ABSOLUTE_LOCAL 3
+#define PATHTYPE_MASK_TYPE 0xFF
+#define PATHTYPE_IS_VOLUME 0x0100
+#define PATHTYPE_IS_SERVER 0x0200
+
+#define VALIDATEPATH_NORMAL 0x0000
+#define VALIDATEPATH_ALLOW_WILDCARDS 0x0001
+#define VALIDATEPATH_ALLOW_ELLIPSE 0x0002
+#define VALIDATEPATH_ALLOW_RELATIVE 0x0004
+#define VALIDATEPATH_ALLOW_UNC 0x0008
+
+DWORD IsValidFilePath (
+ rtl_uString * path,
+ LPCTSTR * lppError,
+ DWORD dwFlags,
+ rtl_uString ** corrected
+);
+
+DWORD GetCaseCorrectPathName (
+ LPCTSTR lpszShortPath, // file name
+ LPTSTR lpszLongPath, // path buffer
+ DWORD cchBuffer // size of path buffer
+);
+
+oslFileError _osl_getSystemPathFromFileURL (
+ rtl_uString * strURL,
+ rtl_uString ** pustrPath,
+ sal_Bool bAllowRelative
+);
+
+oslFileError _osl_getFileURLFromSystemPath (
+ rtl_uString * strPath,
+ rtl_uString ** pstrURL
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_OSL_FILE_URL_H */
diff --git a/sal/osl/w32/procimpl.cxx b/sal/osl/w32/procimpl.cxx
index 3aaea44fd..875d1a097 100644
--- a/sal/osl/w32/procimpl.cxx
+++ b/sal/osl/w32/procimpl.cxx
@@ -59,7 +59,7 @@
#include <string>
//#################################################
-extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle( HANDLE hFile );
+extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle( HANDLE hFile, sal_uInt32 uFlags );
//#################################################
const sal_Unicode NAME_VALUE_SEPARATOR = TEXT('=');
@@ -576,13 +576,13 @@ oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO(
WaitForSingleObject(pProcImpl->m_hProcess, INFINITE);
if (pProcessInputWrite)
- *pProcessInputWrite = osl_createFileHandleFromOSHandle(hInputWrite);
+ *pProcessInputWrite = osl_createFileHandleFromOSHandle(hInputWrite, osl_File_OpenFlag_Write);
if (pProcessOutputRead)
- *pProcessOutputRead = osl_createFileHandleFromOSHandle(hOutputRead);
+ *pProcessOutputRead = osl_createFileHandleFromOSHandle(hOutputRead, osl_File_OpenFlag_Read);
if (pProcessErrorRead)
- *pProcessErrorRead = osl_createFileHandleFromOSHandle(hErrorRead);
+ *pProcessErrorRead = osl_createFileHandleFromOSHandle(hErrorRead, osl_File_OpenFlag_Read);
return osl_Process_E_None;
}
diff --git a/sal/osl/w32/tempfile.cxx b/sal/osl/w32/tempfile.cxx
new file mode 100644
index 000000000..708dbe15c
--- /dev/null
+++ b/sal/osl/w32/tempfile.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: file.cxx,v $
+ * $Revision: 1.0 $
+ *
+ * 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 "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 */
+ 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)
+{
+ WCHAR szBuffer[MAX_PATH];
+ LPWSTR lpBuffer = szBuffer;
+ DWORD nBufferLength = ELEMENTS_OF_ARRAY(szBuffer) - 1;
+
+ DWORD nLength;
+ oslFileError error;
+
+ do
+ {
+ nLength = GetTempPathW( ELEMENTS_OF_ARRAY(szBuffer), lpBuffer );
+ if ( nLength > nBufferLength )
+ {
+ nLength++;
+ lpBuffer = reinterpret_cast<WCHAR*>(alloca( sizeof(WCHAR) * nLength ));
+ nBufferLength = nLength - 1;
+ }
+ } while ( nLength > nBufferLength );
+
+ 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;
+}
diff --git a/sal/workben/makefile.mk b/sal/workben/makefile.mk
index 05afbbb22..5f20dd07b 100644
--- a/sal/workben/makefile.mk
+++ b/sal/workben/makefile.mk
@@ -35,9 +35,10 @@ PRJNAME=sal
TARGET=workben
LIBTARGET=NO
TARGETTYPE=CUI
-ENABLE_EXCEPTIONS=TRUE
+#ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=YES
-TESTAPP=test_osl_getVolInfo
+#TESTAPP=test_osl_getVolInfo
#TESTAPP=test_osl_joinProcess
#TESTAPP=getlocaleinfotest
#TESTAPP=test_osl_joinProcess
@@ -45,6 +46,7 @@ TESTAPP=test_osl_getVolInfo
#TESTAPP=salstattest
#TESTAPP=saldyntest
+TESTAPP=t_readline
#TESTAPP=t_cipher
#TESTAPP=t_digest
#TESTAPP=t_random
@@ -174,6 +176,23 @@ DEF1EXPORTFILE=export.exp
.ENDIF # salstattest
#
+# t_readline
+#
+.IF "$(TESTAPP)" == "t_readline"
+
+CFILES= t_readline.c
+OBJFILES= $(OBJ)$/t_readline.obj
+
+APP1TARGET= t_readline
+APP1OBJS= $(OBJFILES)
+APP1STDLIBS=$(SALLIB)
+APP1DEPN= $(SLB)$/sal.lib
+
+APP1RPATH=UREBIN
+
+.ENDIF # t_readline
+
+#
# t_cipher
#
.IF "$(TESTAPP)" == "t_cipher"
diff --git a/sal/workben/t_layer.c b/sal/workben/t_layer.c
deleted file mode 100644
index e286bcfb7..000000000
--- a/sal/workben/t_layer.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: t_layer.c,v $
- * $Revision: 1.6 $
- *
- * 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.
- *
- ************************************************************************/
-
-#include <sal/types.h>
-#include <rtl/alloc.h>
-#include <osl/diagnose.h>
-#include <osl/interlck.h>
-#ifndef _OSL_ISOCKET_H_
-#include <osl/isocket.h>
-#endif
-
-/*========================================================================
- *
- * osl/debug.c
- *
- *======================================================================*/
-/*
- * __osl_debug_create.
- */
-static oslSocketResult SAL_CALL __osl_debug_create (
- oslSocketDescriptor *socket,
- oslAddrFamily family,
- oslSocketType type,
- oslProtocol protocol)
-{
- oslSocketResult result;
-
- if (!(socket->m_lower))
- {
- oslSocketDescriptor *lower;
- lower = osl_socket_createSocketLayer (osl_socket_getSocketMethods());
- osl_socket_pushSocketLayer (socket, lower);
- }
-
- result = (socket->m_lower->m_methods->m_create)(
- socket->m_lower, family, type, protocol);
- if (!(result == osl_Socket_Ok))
- return (result);
-
- if (!(socket->m_private))
- {
- /* ... */
- }
- return (osl_Socket_Ok);
-}
-
-/*
- * __osl_debug_delete.
- */
-static void SAL_CALL __osl_debug_delete (oslSocketDescriptor *socket)
-{
- if (socket->m_private)
- {
- /* ... */
- }
- if (socket->m_lower)
- {
- (socket->m_lower->m_methods->m_delete)(socket->m_lower);
- osl_socket_deleteSocketLayer (socket->m_lower);
- }
-}
-
-/*
- * __osl_debug_getOption.
- */
-static oslSocketResult SAL_CALL __osl_debug_getOption (
- oslSocketDescriptor *socket,
- oslSocketOptionLevel level,
- oslSocketOption option,
- void *buffer,
- sal_uInt32 length)
-{
- if (level == osl_Socket_LevelSocketLayer)
- {
- /* ... */
- return (osl_Socket_Ok);
- }
-
- return (socket->m_lower->m_methods->m_getoption)(
- socket->m_lower, level, option, buffer, length);
-}
-
-/*
- * __osl_debug_setOption.
- */
-static oslSocketResult SAL_CALL __osl_debug_setOption (
- oslSocketDescriptor *socket,
- oslSocketOptionLevel level,
- oslSocketOption option,
- const void *buffer,
- sal_uInt32 length)
-{
- if (level == osl_Socket_LevelSocketLayer)
- {
- /* ... */
- return (osl_Socket_Ok);
- }
-
- return (socket->m_lower->m_methods->m_setoption)(
- socket->m_lower, level, option, buffer, length);
-}
-
-/*
- * __osl_debug_accept.
- */
-static oslSocketDescriptor* SAL_CALL __osl_debug_accept (
- oslSocketDescriptor *socket, oslSocketAddr *fromaddr)
-{
- oslSocketDescriptor *lower;
- lower = (socket->m_lower->m_methods->m_accept)(socket->m_lower, fromaddr);
- if (lower)
- {
- oslSocketDescriptor *upper;
- upper = osl_socket_createSocketLayer (socket->m_methods);
- osl_socket_pushSocketLayer (upper, lower);
- return (upper);
- }
- return ((oslSocketDescriptor*)NULL);
-}
-
-/*
- * __osl_debug_connect.
- */
-static oslSocketResult SAL_CALL __osl_debug_connect (
- oslSocketDescriptor *socket, oslSocketAddr addr)
-{
- return (socket->m_lower->m_methods->m_connect)(socket->m_lower, addr);
-}
-
-/*
- * __osl_debug_close.
- */
-static void SAL_CALL __osl_debug_close (oslSocketDescriptor *socket)
-{
- (socket->m_lower->m_methods->m_close)(socket->m_lower);
-}
-
-/*
- * __osl_shutdown.
- */
-static void SAL_CALL __osl_debug_shutdown (
- oslSocketDescriptor *socket, oslSocketDirection direction)
-{
- (socket->m_lower->m_methods->m_shutdown)(socket->m_lower, direction);
-}
-
-/*
- * __osl_debug_methods.
- */
-static oslSocketMethods __osl_debug_methods =
-{
- NULL /* initialized on demand */
-};
-
-/*
- * osl_debug_getSocketMethods.
- */
-const oslSocketMethods* SAL_CALL osl_debug_getSocketMethods (void)
-{
- static oslInterlockedCount nonce = 0;
- if (osl_incrementInterlockedCount (&nonce) == 1)
- {
- const oslSocketMethods *methods = osl_socket_getDefaultSocketMethods();
- __osl_debug_methods = *methods;
-
- __osl_debug_methods.m_create = __osl_debug_create;
- __osl_debug_methods.m_delete = __osl_debug_delete;
-
- __osl_debug_methods.m_getoption = __osl_debug_getOption;
- __osl_debug_methods.m_setoption = __osl_debug_setOption;
-
- __osl_debug_methods.m_accept = __osl_debug_accept;
- __osl_debug_methods.m_connect = __osl_debug_connect;
- __osl_debug_methods.m_close = __osl_debug_close;
-
- __osl_debug_methods.m_shutdown = __osl_debug_shutdown;
-
- osl_incrementInterlockedCount (&nonce);
- }
-
- osl_decrementInterlockedCount (&nonce);
- return (&__osl_debug_methods);
-}
-
-/*========================================================================
- *
- * osl/socket.c (physical, bottom layer).
- *
- *======================================================================*/
-#if 0 /* NYI */
-
-static oslSocketResult SAL_CALL __osl_socket_create (
- oslSocketDescriptor *socket,
- oslAddrFamily family,
- oslSocketType type,
- oslProtocol protocol)
-{
-#if OSL_DEBUG_LEVEL > 1
- const oslSocketMethods *debug = osl_debug_getSocketMethods();
- if (!(socket->m_upper || socket->m_upper->m_methods == debug))
- {
- oslSocketDescriptor *upper;
-
- upper = osl_socket_createSocketLayer (debug);
- osl_socket_pushSocketLayer (upper, socket);
-
- return (upper->m_methods->m_create)(upper, family, type, protocol);
- }
-#endif /* OSL_DEBUG_LEVEL */
- if (!(socket->m_private))
- {
- /* ... */
- socket->m_private = osl_createSocket (family, type, protocol);
- }
- return (osl_Socket_Ok);
-}
-
-#endif /* NYI */
-
-/*========================================================================
- *
- * main.
- *
- *======================================================================*/
-int SAL_CALL main (int argc, char **argv)
-{
- oslSocketDescriptor *socket;
-
- socket = osl_socket_createSocketLayer (osl_debug_getSocketMethods());
- if (socket)
- {
- oslSocketDescriptor *connection;
- oslSocketResult result;
- oslSocketAddr addr, from;
- sal_Int32 option = 1;
-
- result = osl_socket_create (
- socket,
- osl_Socket_FamilyInet,
- osl_Socket_TypeStream,
- osl_Socket_ProtocolIp);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_setOption (
- socket,
- osl_Socket_LevelSocket,
- osl_Socket_OptionReuseAddr,
- &option, sizeof(option));
- OSL_ASSERT(result == osl_Socket_Ok);
-
- addr = osl_createEmptySocketAddr (osl_Socket_FamilyInet);
- osl_setInetPortOfSocketAddr (addr, 7777);
-
- result = osl_socket_bind (socket, addr);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_listen (socket, 1);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- connection = osl_socket_accept (socket, &from);
- if (connection)
- {
- sal_Char buffer[1024];
- sal_Int32 k, n = sizeof(buffer);
- oslSocketMsgFlag flag = osl_Socket_MsgNormal;
-
- while ((k = osl_socket_recv (connection, buffer, n, flag)) > 0)
- {
- if (osl_socket_send (connection, buffer, k, flag) < 0)
- break;
- }
-
- osl_socket_close (connection);
- osl_socket_delete (connection);
-
- osl_socket_deleteSocketLayer (connection);
- }
-
- osl_socket_close (socket);
- osl_socket_delete (socket);
-
- osl_socket_deleteSocketLayer (socket);
- }
-
- return 0;
-}
-
diff --git a/sal/workben/t_readline.c b/sal/workben/t_readline.c
new file mode 100644
index 000000000..9cbc7d39c
--- /dev/null
+++ b/sal/workben/t_readline.c
@@ -0,0 +1,58 @@
+/*
+ * t_readline.c
+ */
+
+#include "osl/file.h"
+
+#include "osl/diagnose.h"
+#include "rtl/ustring.h"
+#include "rtl/byteseq.h"
+
+#include <stdio.h>
+
+/* main */
+int main (int argc, char ** argv)
+{
+ if (argc > 1)
+ {
+ oslFileError result;
+ oslFileHandle hFile = 0;
+
+ rtl_uString * pSystemPath = 0;
+ rtl_uString * pFileUrl = 0;
+
+ rtl_uString_newFromAscii (&pSystemPath, argv[1]);
+
+ result = osl_getFileURLFromSystemPath (pSystemPath, &pFileUrl);
+ rtl_uString_release (pSystemPath), pSystemPath = 0;
+ if (result != osl_File_E_None)
+ return (result);
+
+ result = osl_openFile (pFileUrl, &hFile, osl_File_OpenFlag_Read);
+ rtl_uString_release (pFileUrl), pFileUrl = 0;
+ if (result == osl_File_E_None)
+ {
+ sal_Sequence * pBuffer = 0;
+ for ( ;; )
+ {
+ sal_Int32 i, n;
+
+ result = osl_readLine (hFile, &pBuffer);
+ if (result != osl_File_E_None)
+ break;
+#if 0
+ if (pBuffer->elements[0] == 0)
+ /* @@@ cannot distinguish empty line from EOF @@@ */
+ break;
+#endif
+ for (i = 0, n = pBuffer->nElements; i < n; i++)
+ printf ("%c", (char)(pBuffer->elements[i]));
+ printf("\n");
+ }
+
+ rtl_byte_sequence_release (pBuffer), pBuffer = 0;
+ (void) osl_closeFile (hFile);
+ }
+ }
+ return 0;
+}
diff --git a/sal/workben/t_tls.c b/sal/workben/t_tls.c
deleted file mode 100644
index 91d0891de..000000000
--- a/sal/workben/t_tls.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: t_tls.c,v $
- * $Revision: 1.5 $
- *
- * 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.
- *
- ************************************************************************/
-
-#include <sal/types.h>
-#include <rtl/alloc.h>
-#include <rtl/ustring.h>
-#include <osl/diagnose.h>
-#include <osl/file.h>
-#include <osl/interlck.h>
-#ifndef _OSL_ISOCKET_H_
-#include <osl/isocket.h>
-#endif
-
-#ifndef _OSL_TLS_H_
-#include <osl/tls.h>
-#endif
-
-#include <string.h>
-#include <stdio.h>
-
-/*========================================================================
- *
- * Internals.
- *
- *======================================================================*/
-void SAL_CALL __rtl_sequence_release (sal_Sequence *value)
-{
- if (value)
- {
- if (osl_decrementInterlockedCount (&(value->nRefCount)) == 0)
- rtl_freeMemory (value);
- }
-}
-
-void SAL_CALL __rtl_sequence_new (sal_Sequence **value, sal_Int32 length)
-{
- if (value)
- {
- __rtl_sequence_release (*value);
-
- *value = (sal_Sequence*)rtl_allocateMemory (
- SAL_SEQUENCE_HEADER_SIZE + length);
-
- (*value)->nRefCount = 1;
- (*value)->nElements = 0;
- }
-}
-
-void load_sequence (sal_Sequence **ppSequence, const sal_Char *name)
-{
- oslFileError result;
- rtl_uString *pName, *pPath;
-
- if (ppSequence)
- {
- __rtl_sequence_release (*ppSequence);
- *ppSequence = NULL;
- }
-
- pName = NULL;
- rtl_uString_newFromAscii (&pName, name);
-
- pPath = NULL;
- result = osl_searchNormalizedPath (pName, NULL, &pPath);
- if (result == osl_File_E_None)
- {
- oslFileHandle hFile;
-
- result = osl_openFile (pPath, &hFile, osl_File_OpenFlag_Read);
- if (result == osl_File_E_None)
- {
- sal_uInt64 nSize = 0, nRead = 0;
-
- osl_setFilePos (hFile, osl_Pos_End, 0);
- osl_getFilePos (hFile, &nSize);
- osl_setFilePos (hFile, osl_Pos_Absolut, 0);
-
- __rtl_sequence_new (ppSequence, (sal_Int32)nSize);
-
- osl_readFile (hFile, (*ppSequence)->elements, nSize, &nRead);
- (*ppSequence)->nElements = (sal_Int32)nRead;
- }
- osl_closeFile (hFile);
-
- rtl_uString_release (pPath);
- }
-
- rtl_uString_release (pName);
-}
-
-/*========================================================================
- *
- * main.
- *
- *======================================================================*/
-int SAL_CALL main (int argc, char **argv)
-{
- static const sal_Char p[] = "GET / HTTP/1.0\015\012\015\012";
- oslSocketDescriptor *socket;
-
-
- socket = osl_socket_createSocketLayer (osl_tls_getSocketMethods());
- if (socket)
- {
- oslSocketAddr target;
- oslSocketResult result;
- oslSocketMsgFlag flag = osl_Socket_MsgNormal;
- rtl_uString *dotted = NULL;
-
-
- rtl_uString_newFromAscii (&dotted, argv[1]);
- target = osl_createInetSocketAddr (dotted, 443);
- rtl_uString_release (dotted);
-
- result = osl_socket_create (
- socket,
- osl_Socket_FamilyInet,
- osl_Socket_TypeStream,
- osl_Socket_ProtocolIp);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_connect (socket, target);
- osl_destroySocketAddr (target);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_connect_handshake (socket, target);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- if (osl_socket_send (socket, p, strlen(p), flag) > 0)
- {
- sal_Char buffer[1024];
- sal_Int32 k, n = sizeof(buffer);
-
- while ((k = osl_socket_recv (socket, buffer, n, flag)) > 0)
- fwrite (buffer, 1, k, stdout);
- }
-
- osl_socket_shutdown (socket, osl_Socket_DirReadWrite);
- osl_socket_close (socket);
-
- osl_socket_delete (socket);
- osl_socket_deleteSocketLayer (socket);
- }
-
-
- socket = osl_socket_createSocketLayer (osl_tls_getSocketMethods());
- if (socket)
- {
- oslSocketDescriptor *connection;
- oslSocketResult result;
- oslSocketAddr addr, from;
- sal_Int32 option = 1;
- sal_Sequence *data = NULL;
-
-
- result = osl_socket_create (
- socket,
- osl_Socket_FamilyInet,
- osl_Socket_TypeStream,
- osl_Socket_ProtocolIp);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_setOption (
- socket,
- osl_Socket_LevelSocket,
- osl_Socket_OptionReuseAddr,
- &option, sizeof(option));
- OSL_ASSERT(result == osl_Socket_Ok);
-
- addr = osl_createEmptySocketAddr (osl_Socket_FamilyInet);
- osl_setInetPortOfSocketAddr (addr, 7777);
-
- result = osl_socket_bind (socket, addr);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- load_sequence (&data, "s_cert.der");
- if (data && data->nElements)
- {
- result = osl_socket_setOption (
- socket,
- osl_Socket_LevelTLS,
- osl_Socket_OptionCertificate,
- data->elements, data->nElements);
- OSL_ASSERT(result == osl_Socket_Ok);
- }
-
- load_sequence (&data, "s_pkey.der");
- if (data && data->nElements)
- {
- result = osl_socket_setOption (
- socket,
- osl_Socket_LevelTLS,
- osl_Socket_OptionPrivateKey,
- data->elements, data->nElements);
- OSL_ASSERT(result == osl_Socket_Ok);
- }
- __rtl_sequence_release (data);
-
- result = osl_socket_listen (socket, 1);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- connection = osl_socket_accept (socket, &from);
- if (connection)
- {
- sal_Char buffer[1024];
- sal_Int32 k, n = sizeof(buffer);
- oslSocketMsgFlag flag = osl_Socket_MsgNormal;
-
- result = osl_socket_accept_handshake (connection, from);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- while ((k = osl_socket_recv (connection, buffer, n, flag)) > 0)
- {
- if (osl_socket_send (connection, buffer, k, flag) < 0)
- break;
- }
-
- osl_socket_close (connection);
-
- osl_socket_delete (connection);
- osl_socket_deleteSocketLayer (connection);
- }
-
- osl_socket_delete (socket);
- osl_socket_deleteSocketLayer (socket);
- }
-
- return 0;
-}
-
diff --git a/sal/workben/t_zip.c b/sal/workben/t_zip.c
deleted file mode 100644
index 5105b5b25..000000000
--- a/sal/workben/t_zip.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: t_zip.c,v $
- * $Revision: 1.5 $
- *
- * 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.
- *
- ************************************************************************/
-
-#include <sal/types.h>
-#include <rtl/ustring.h>
-#include <osl/diagnose.h>
-#include <osl/thread.h>
-#ifndef _OSL_ZSOCKET_H_
-#include <osl/zsocket.h>
-#endif
-
-#include <stdio.h>
-
-/*========================================================================
- *
- * internals.
- *
- *======================================================================*/
-void SAL_CALL clientSocketReader (void *pData)
-{
- oslSocketDescriptor *socket;
-
- socket = (oslSocketDescriptor*)pData;
- if (socket)
- {
- sal_Char buffer[128];
- sal_Int32 k, n = sizeof(buffer);
- oslSocketMsgFlag flag = osl_Socket_MsgNormal;
-
- while ((k = osl_socket_recv (socket, buffer, n, flag)) > 0)
- {
- fwrite (buffer, 1, k, stdout);
- fflush (stdout);
- }
- }
-}
-
-/*========================================================================
- *
- * main.
- *
- *======================================================================*/
-int SAL_CALL main (int argc, char **argv)
-{
- oslSocketDescriptor *socket;
-
- socket = osl_socket_createSocketLayer (osl_zlib_getSocketMethods());
- if (socket)
- {
- oslSocketAddr addr = 0;
- oslSocketResult result;
-
- result = osl_socket_create (
- socket,
- osl_Socket_FamilyInet,
- osl_Socket_TypeStream,
- osl_Socket_ProtocolIp);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- if (argc > 1)
- {
- rtl_uString *host = 0;
-
- rtl_uString_newFromAscii (&host, argv[1]);
- addr = osl_resolveHostname (host);
- rtl_uString_release (host);
- }
-
- if (addr)
- {
- sal_Char buffer[128];
- sal_Int32 k, n = sizeof(buffer);
- oslSocketMsgFlag flag = osl_Socket_MsgNormal;
- oslThread reader;
-
- osl_setInetPortOfSocketAddr (addr, 7777);
-
- result = osl_socket_connect (socket, addr);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_connect_handshake (socket, addr);
- osl_destroySocketAddr (addr);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- reader = osl_createSuspendedThread (clientSocketReader, socket);
- OSL_ASSERT(reader);
- osl_resumeThread (reader);
-
- while ((k = fread (buffer, 1, n, stdin)) > 0)
- {
- if (osl_socket_send (socket, buffer, k, flag) < 0)
- break;
- }
-
- osl_socket_shutdown (socket, osl_Socket_DirReadWrite);
- osl_socket_close (socket);
-
- osl_joinWithThread (reader);
- osl_destroyThread (reader);
- }
- else
- {
- oslSocketDescriptor *connection;
- oslSocketAddr from = 0;
- sal_Int32 option = 1;
-
- addr = osl_createEmptySocketAddr (osl_Socket_FamilyInet);
- osl_setInetPortOfSocketAddr (addr, 7777);
-
- result = osl_socket_setOption (
- socket,
- osl_Socket_LevelSocket,
- osl_Socket_OptionReuseAddr,
- &option, sizeof(option));
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_bind (socket, addr);
- osl_destroySocketAddr (addr);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- result = osl_socket_listen (socket, 1);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- connection = osl_socket_accept (socket, &from);
- if (connection)
- {
- sal_Char buffer[64];
- sal_Int32 k, n = sizeof(buffer);
- oslSocketMsgFlag flag = osl_Socket_MsgNormal;
-
- result = osl_socket_accept_handshake (connection, from);
- osl_destroySocketAddr (from);
- OSL_ASSERT(result == osl_Socket_Ok);
-
- while ((k = osl_socket_recv (connection, buffer, n, flag)) > 0)
- {
- if (osl_socket_send (connection, buffer, k, flag) < 0)
- break;
- }
-
- osl_socket_close (connection);
-
- osl_socket_delete (connection);
- osl_socket_deleteSocketLayer (connection);
- }
-
- osl_socket_close (socket);
- }
-
- osl_socket_delete (socket);
- osl_socket_deleteSocketLayer (socket);
- }
-
- return 0;
-}
-
diff --git a/store/source/lockbyte.cxx b/store/source/lockbyte.cxx
index a38aa7689..a03628bfb 100644
--- a/store/source/lockbyte.cxx
+++ b/store/source/lockbyte.cxx
@@ -297,7 +297,7 @@ struct FileHandle
if (result == osl_File_E_EXIST)
{
// Already existing (O_CREAT | O_EXCL).
- result = osl_openFile (aFileUrl.pData, &m_handle, osl_File_OpenFlag_Write);
+ result = osl_openFile (aFileUrl.pData, &m_handle, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write);
if ((result == osl_File_E_None) && (eAccessMode == store_AccessCreate))
{
// Truncate existing file.
diff --git a/store/workben/makefile.mk b/store/workben/makefile.mk
index 334585710..4b58d2640 100644
--- a/store/workben/makefile.mk
+++ b/store/workben/makefile.mk
@@ -93,11 +93,12 @@ APP3STDLIBS= $(STOREDBGLIB)
APP3STDLIBS+= $(SALLIB)
APP3DEPN= $(STOREDBGLIB)
- APP4TARGET= t_store
- APP4OBJS= $(OBJ)$/t_store.obj
- APP4STDLIBS= $(STORELIB)
- APP4STDLIBS+= $(SALLIB)
- APP4DEPN= $(SLB)$/store.lib
+APP4TARGET= t_store
+APP4OBJS= $(OBJ)$/t_store.obj
+APP4STDLIBS= $(STORELIB)
+APP4STDLIBS+= $(SALLIB)
+APP4DEPN= $(SLB)$/store.lib
+APP4RPATH= UREBIN
APP5TARGET= t_leak
APP5OBJS= $(OBJ)$/t_leak.obj