blob: b9296b7ef89d44cd00578df03dcb0707098985dd [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_tools.hxx"
#ifdef _MSC_VER
#pragma warning (push,1)
#endif
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#ifdef _MSC_VER
#pragma warning (pop)
#endif
#include "wntmsc.hxx"
#include <tools/errinf.hxx>
#include <tools/debug.hxx>
#include <tools/list.hxx>
#include <tools/wldcrd.hxx>
#include <tools/fsys.hxx>
#include <tools/bigint.hxx>
DECLARE_LIST( DirEntryList, DirEntry* );
DECLARE_LIST( FSysSortList, FSysSort* );
DECLARE_LIST( FileStatList, FileStat* );
int Sys2SolarError_Impl( int nSysErr );
static sal_Bool bLastCaseSensitive = sal_False;
//--------------------------------------------------------------------
ByteString Upper_Impl( const ByteString &rStr )
{
ByteString aRet( rStr.GetBuffer() ); // es muss ein neuer String entstehen!
CharUpperBuff( (char*) aRet.GetBuffer(), aRet.Len() );
return aRet;
}
//--------------------------------------------------------------------
DIR *opendir( const char* pPfad )
{
DIR *pDir = new DIR;
if ( pDir )
pDir->p = (char*) pPfad;
return pDir;
}
struct dirent *readdir( DIR *pDir )
{
bool bOk = false;
if ( pDir->p )
{
char *pBuf = new char[ strlen( pDir->p ) + 5 ];
if ( pBuf )
{
// *.* dahinter, ggf mit "\\" abtrennen (falls nicht schon da)
strcpy( pBuf, pDir->p );
strcat( pBuf, "\\*.*" + ( *(pBuf + strlen( pBuf ) - 1 ) == '\\' ) );
CharUpperBuff( pBuf, strlen(pBuf) );
pDir->h = FindFirstFile( pBuf, &pDir->aDirEnt );
bOk = pDir->h != INVALID_HANDLE_VALUE;
pDir->p = NULL;
delete [] pBuf;
}
else
pDir->h = INVALID_HANDLE_VALUE;
}
else
{
bOk = FindNextFile( pDir->h, &pDir->aDirEnt );
}
return bOk ? &pDir->aDirEnt : NULL;
}
int closedir( DIR *pDir )
{
sal_Bool bOk = sal_False;
if ( pDir )
{
bOk = 0 != pDir->p || FindClose( pDir->h );
delete pDir;
}
return bOk;
}
/*************************************************************************
|*
|* DirEntry::GetPathStyle() const
|*
|* Beschreibung
|* Ersterstellung MI 11.05.95
|* Letzte Aenderung MI 11.05.95
|*
*************************************************************************/
ErrCode GetPathStyle_Impl( const String &rDevice, FSysPathStyle &rStyle )
{
ByteString aRootDir(rDevice, osl_getThreadTextEncoding());
if ( aRootDir.Len() && aRootDir.GetBuffer()[aRootDir.Len()-1] != '\\' )
aRootDir += '\\';
char sVolumeName[256];
char sFileSysName[16];
DWORD nSerial[2];
DWORD nMaxCompLen[2];
DWORD nFlags[2];
// Windows95 hat VFAT, WindowsNT nicht
DWORD nVer = GetVersion();
sal_Bool bW95 = ( nVer & 0xFF ) >= 4;
FSysFailOnErrorImpl();
rStyle = FSYS_STYLE_UNKNOWN;
if ( GetVolumeInformation(
(char*) aRootDir.GetBuffer(),
sVolumeName, 256, (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen,
(LPDWORD) &nFlags, sFileSysName, 16 ) )
{
// FAT/VFAT?
if ( 0 == strcmp( "FAT", sFileSysName ) )
rStyle = bW95 ? FSYS_STYLE_VFAT : FSYS_STYLE_FAT;
// NTFS?
else if ( 0 == strcmp( "NTFS", sFileSysName ) )
rStyle = FSYS_STYLE_NTFS;
// HPFS?
else if ( 0 == strcmp( "HPFS", sFileSysName ) )
rStyle = FSYS_STYLE_HPFS;
// NWCOMPA/NWFS?
else if ( 0 == strncmp( "NW", sFileSysName, 2 ) )
rStyle = FSYS_STYLE_NWFS;
return ERRCODE_NONE;
}
return ERRCODE_IO_INVALIDDEVICE;
}
FSysPathStyle DirEntry::GetPathStyle( const String &rDevice )
{
FSysPathStyle eStyle;
GetPathStyle_Impl( rDevice, eStyle );
return eStyle;
}
/*************************************************************************
|*
|* DirEntry::IsCaseSensitive()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 10.06.93
|* Letzte Aenderung TPF 26.02.1999
|*
*************************************************************************/
sal_Bool DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
{
if (eFormatter==FSYS_STYLE_HOST)
{
/*
DirEntry aRoot(*this);
aRoot.ToAbs();
aRoot = aRoot[Level()-1];
String aRootDir = aRoot.GetFull(FSYS_STYLE_HOST, sal_True);
char sVolumeName[256];
DWORD nVolumeSerial;
DWORD nMaxCompLen;
DWORD nFlags;
char sFileSysName[16];
if ( GetVolumeInformation( (char*) aRootDir.GetStr(),
sVolumeName,
256,
(LPDWORD) &nVolumeSerial,
(LPDWORD) &nMaxCompLen,
(LPDWORD) &nFlags,
sFileSysName,
16 ))
{
return (nFlags & FS_CASE_SENSITIVE) ? sal_True : sal_False;
}
else
{
return sal_False;
}
*/
//
// guter versuch, aber FS_CASE_SENSITIVE ist D?nnsinn in T?ten:
//
// sFileSysName FS_CASE_SENSITIVE
// FAT sal_False
// NTFS sal_True !!!
// NWCompat sal_False
// Samba sal_False
//
// NT spricht auch NTFS lediglich case preserving an, also ist unter NT alles case insensitiv
//
return sal_False;
}
else
{
sal_Bool isCaseSensitive = sal_False; // ich bin unter win32, also ist der default case insensitiv
switch ( eFormatter )
{
case FSYS_STYLE_MAC:
case FSYS_STYLE_FAT:
case FSYS_STYLE_VFAT:
case FSYS_STYLE_NTFS:
case FSYS_STYLE_NWFS:
case FSYS_STYLE_HPFS:
case FSYS_STYLE_DETECT:
{
isCaseSensitive = sal_False;
break;
}
case FSYS_STYLE_SYSV:
case FSYS_STYLE_BSD:
{
isCaseSensitive = sal_True;
break;
}
default:
{
isCaseSensitive = sal_False; // ich bin unter win32, also ist der default case insensitiv
break;
}
}
return isCaseSensitive;
}
}
/*************************************************************************
|*
|* DirEntry::ToAbs()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 26.04.91
|* Letzte Aenderung MA 02.12.91
|*
*************************************************************************/
sal_Bool DirEntry::ToAbs()
{
DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
if ( FSYS_FLAG_VOLUME == eFlag )
{
eFlag = FSYS_FLAG_ABSROOT;
return sal_True;
}
if ( IsAbs() )
{
return sal_True;
}
char sBuf[256];
char *pOld;
ByteString aFullName( GetFull(), osl_getThreadTextEncoding() );
FSysFailOnErrorImpl();
if ( GetFullPathName((char*)aFullName.GetBuffer(),256,sBuf,&pOld) > 511 )
return sal_False;
*this = DirEntry( String(sBuf, osl_getThreadTextEncoding() ));
return sal_True;
}
/*************************************************************************
|*
|* DirEntry::GetVolume()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 27.08.92
|* Letzte Aenderung MI 28.08.92
|*
*************************************************************************/
String DirEntry::GetVolume() const
{
DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
String aRet;
const DirEntry *pTop = ImpGetTopPtr();
ByteString aName = ByteString( pTop->aName ).ToLowerAscii();
if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT ||
pTop->eFlag == FSYS_FLAG_RELROOT ||
pTop->eFlag == FSYS_FLAG_VOLUME )
&& aName != "a:" && aName != "b:" && Exists() )
{
char sFileSysName[256];
char sVolumeName[256];
DWORD nVolumeNameLen = 256;
DWORD nSerial[2];
DWORD nMaxCompLen[2];
DWORD nFlags[2];
ByteString aRootDir = pTop->aName;
FSysFailOnErrorImpl();
// Network-Device zuerst probieren wegen langsamer Samba-Drives
if ( !WNetGetConnection( (char*) aRootDir.GetBuffer(),
sVolumeName, &nVolumeNameLen ) )
aRet = String( sVolumeName, osl_getThreadTextEncoding());
// dann den VolumeNamen fuer lokale Drives
if ( aRet.Len() == 0 )
{
aRootDir += "\\";
if ( GetVolumeInformation( (char*) aRootDir.GetBuffer(),
sVolumeName, 256,
(LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen,
(LPDWORD) &nFlags, sFileSysName, 256 ) )
aRet = String( sVolumeName, osl_getThreadTextEncoding());
}
}
return aRet;
}
/*************************************************************************
|*
|* DirEntry::SetCWD()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 26.04.91
|* Letzte Aenderung MI 21.05.92
|*
*************************************************************************/
sal_Bool DirEntry::SetCWD( sal_Bool bSloppy ) const
{
DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
FSysFailOnErrorImpl();
if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() )
return sal_True;
if ( SetCurrentDirectory(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
{
return sal_True;
}
if ( bSloppy && pParent &&
SetCurrentDirectory(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
{
return sal_True;
}
return sal_False;
}
//-------------------------------------------------------------------------
USHORT DirReader_Impl::Init()
{
// Block-Devices auflisten?
if ( pDir->eAttrMask & FSYS_KIND_BLOCK )
{
// CWD merken
DirEntry aCurrentDir;
aCurrentDir.ToAbs();
// einzeln auf Existenz und Masken-konformit"at pr"ufen
USHORT nRead = 0;
char sDrive[3] = { '?', ':', 0 };
char sRoot[4] = { '?', ':', '\\', 0 };
for ( char c = 'a'; c <= 'z'; c++ )
{
sDrive[0] = c;
sRoot[0] = c;
DirEntry* pDrive = new DirEntry( sDrive, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST );
if ( pDir->aNameMask.Matches( String( ByteString(sDrive), osl_getThreadTextEncoding())) && GetDriveType( sRoot ) != 1 )
{
if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
{
FileStat *pNewStat = new FileStat( *pDrive );
pDir->ImpSortedInsert( pDrive, pNewStat );
}
else
pDir->ImpSortedInsert( pDrive, NULL );
++nRead;
}
else
delete pDrive;
}
// CWD restaurieren
aCurrentDir.SetCWD();
return nRead;
}
return 0;
}
//-------------------------------------------------------------------------
USHORT DirReader_Impl::Read()
{
// Directories und Files auflisten?
if ( ( pDir->eAttrMask & FSYS_KIND_DIR ||
pDir->eAttrMask & FSYS_KIND_FILE ) &&
( ( pDosEntry = readdir( pDosDir ) ) != NULL ) )
{
// Gross/Kleinschreibung nicht beruecksichtigen
ByteString aLowerName = pDosEntry->d_name;
CharLowerBuff( (char*) aLowerName.GetBuffer(), aLowerName.Len() );
// Flags pruefen
sal_Bool bIsDirAndWantsDir =
( ( pDir->eAttrMask & FSYS_KIND_DIR ) &&
#ifdef ICC
( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") ||
strcmp(pDosEntry->d_name,"..")) ) );
#else
( pDosEntry->d_type & DOS_DIRECT ) );
#endif
sal_Bool bIsFileAndWantsFile =
( ( pDir->eAttrMask & FSYS_KIND_FILE ) &&
#ifdef ICC
!( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") ||
strcmp(pDosEntry->d_name,"..")) ) &&
#else
!( pDosEntry->d_type & DOS_DIRECT ) &&
#endif
!( pDosEntry->d_type & DOS_VOLUMEID ) );
sal_Bool bIsHidden = (pDosEntry->d_type & _A_HIDDEN) != 0;
sal_Bool bWantsHidden = 0 == ( pDir->eAttrMask & FSYS_KIND_VISIBLE );
if ( ( bIsDirAndWantsDir || bIsFileAndWantsFile ) &&
( bWantsHidden || !bIsHidden ) &&
pDir->aNameMask.Matches( String(aLowerName, osl_getThreadTextEncoding()) ) )
{
#ifdef DBG_UTIL
DbgOutf( "%s %s flags:%x found",
pDosEntry->d_name,
bIsFileAndWantsFile ? "file" : "dir",
pDosEntry->d_type );
#endif
DirEntryFlag eFlag =
0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT
: 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT
: FSYS_FLAG_NORMAL;
DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name),
eFlag, FSYS_STYLE_NTFS );
#ifdef FEAT_FSYS_DOUBLESPEED
pTemp->ImpSetStat( new FileStat( (void*) pDosDir, (void*) 0 ) );
#endif
if ( pParent )
pTemp->ImpChangeParent( new DirEntry( *pParent ), sal_False );
if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
{
FileStat *pNewStat = new FileStat( (void*) pDosDir, (void*) 0 );
pDir->ImpSortedInsert( pTemp, pNewStat );
}
else
pDir->ImpSortedInsert( pTemp, NULL );
return 1;
}
#ifdef DBG_UTIL
else
DbgOutf( "%s flags:%x skipped",
pDosEntry->d_name,
pDosEntry->d_type );
#endif
}
else
bReady = sal_True;
return 0;
}
/*************************************************************************
|*
|* InitFileStat()
|*
|* Beschreibung gemeinsamer Teil der Ctoren fuer FileStat
|* Ersterstellung MI 28.08.92
|* Letzte Aenderung MI 28.08.92
|*
*************************************************************************/
void FileStat::ImpInit( void* p )
{
_WIN32_FIND_DATAA *pDirEnt = (_WIN32_FIND_DATAA*) p;
nError = FSYS_ERR_OK;
nSize = pDirEnt->nFileSizeLow;
SYSTEMTIME aSysTime;
FILETIME aLocTime;
// use the last write date / time when the creation date / time isn't set
if ( ( pDirEnt->ftCreationTime.dwLowDateTime == 0 ) &&
( pDirEnt->ftCreationTime.dwHighDateTime == 0 ) )
{
pDirEnt->ftCreationTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime;
pDirEnt->ftCreationTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime;
}
// use the last write date / time when the last accessed date / time isn't set
if ( ( pDirEnt->ftLastAccessTime.dwLowDateTime == 0 ) &&
( pDirEnt->ftLastAccessTime.dwHighDateTime == 0 ) )
{
pDirEnt->ftLastAccessTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime;
pDirEnt->ftLastAccessTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime;
}
FileTimeToLocalFileTime( &pDirEnt->ftCreationTime, &aLocTime );
FileTimeToSystemTime( &aLocTime, &aSysTime );
aDateCreated = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
aTimeCreated = Time( aSysTime.wHour, aSysTime.wMinute,
aSysTime.wSecond, 0 );
FileTimeToLocalFileTime( &pDirEnt->ftLastWriteTime, &aLocTime );
FileTimeToSystemTime( &aLocTime, &aSysTime );
aDateModified = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
aTimeModified = Time( aSysTime.wHour, aSysTime.wMinute,
aSysTime.wSecond, 0 );
FileTimeToLocalFileTime( &pDirEnt->ftLastAccessTime, &aLocTime );
FileTimeToSystemTime( &aLocTime, &aSysTime );
aDateAccessed = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
aTimeAccessed = Time( aSysTime.wHour, aSysTime.wMinute,
aSysTime.wSecond, 0 );
nKindFlags = FSYS_KIND_FILE;
if ( pDirEnt->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
nKindFlags = FSYS_KIND_DIR;
}
/*************************************************************************
|*
|* FileStat::FileStat()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 27.08.92
|* Letzte Aenderung MI 28.08.92
|*
*************************************************************************/
FileStat::FileStat( const void *pInfo, // struct dirent
const void * ): // dummy
aDateCreated(0),
aTimeCreated(0),
aDateModified(0),
aTimeModified(0),
aDateAccessed(0),
aTimeAccessed(0)
{
ImpInit( ( (dirent*) pInfo ) );
}
/*************************************************************************
|*
|* FileStat::Update()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 27.08.92
|* Letzte Aenderung MI 28.08.92
|*
*************************************************************************/
#ifdef _MSC_VER
#pragma warning(push, 1)
#pragma warning(disable: 4917)
#endif
#include <shlobj.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#ifdef UNICODE
#define lstrchr wcschr
#define lstrncmp wcsncmp
#else
#define lstrchr strchr
#define lstrncmp strncmp
#endif
//---------------------------------------------------------------------------
void SHFreeMem( void *p )
{
LPMALLOC pMalloc = NULL;
if ( SUCCEEDED(SHGetMalloc(&pMalloc)) )
{
pMalloc->Free( p );
pMalloc->Release();
}
}
//---------------------------------------------------------------------------
HRESULT SHGetIDListFromPath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl )
{
if ( IsBadWritePtr(ppidl, sizeof(LPITEMIDLIST)) )
return E_INVALIDARG;
LPSHELLFOLDER pDesktopFolder = NULL;
HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder );
if ( FAILED(hResult) )
return hResult;
ULONG chEaten = lstrlen( pszPath );
DWORD dwAttributes = FILE_ATTRIBUTE_DIRECTORY;
#ifdef UNICODE
LPOLESTR wszPath = pszPath;
#else
WCHAR wszPath[MAX_PATH];
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszPath, -1, wszPath, MAX_PATH );
#endif
hResult = pDesktopFolder->ParseDisplayName( hwndOwner, (LPBC)NULL, wszPath, &chEaten, ppidl, &dwAttributes );
pDesktopFolder->Release();
return hResult;
}
//---------------------------------------------------------------------------
HRESULT SHGetFolderFromIDList( LPCITEMIDLIST pidl, LPSHELLFOLDER *ppFolder )
{
if ( IsBadWritePtr(ppFolder, sizeof(LPSHELLFOLDER)) )
return E_INVALIDARG;
*ppFolder = NULL;
LPSHELLFOLDER pDesktopFolder = NULL;
HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder );
if ( FAILED(hResult) )
return hResult;
hResult = pDesktopFolder->BindToObject( pidl, (LPBC)NULL, IID_IShellFolder, (LPVOID *)ppFolder );
pDesktopFolder->Release();
return hResult;
}
//---------------------------------------------------------------------------
HRESULT SHResolvePath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl )
{
// If hwndOwner is NULL, use the desktop window, because dialogs need a parent
#ifdef BOOTSTRAP
return NO_ERROR;
#else
if ( !hwndOwner )
hwndOwner = GetDesktopWindow();
HRESULT hResult = NOERROR;
LPTSTR pszPathCopy;
LPTSTR pszTrailingPath;
TCHAR cBackup = 0;
// First make a copy of the path
pszPathCopy = new TCHAR[lstrlen(pszPath) + 1];
if ( pszPathCopy )
lstrcpy( pszPathCopy, pszPath );
else
return E_OUTOFMEMORY;
// Determine the first token
if ( !lstrncmp( pszPathCopy, "\\\\", 2 ) )
pszTrailingPath = lstrchr( pszPathCopy + 2, '\\' );
else
pszTrailingPath = lstrchr( pszPathCopy, '\\' );
// Now scan the path tokens
while ( SUCCEEDED(hResult) )
{
if ( pszTrailingPath )
{
cBackup = *(++pszTrailingPath);
*pszTrailingPath = 0;
}
LPITEMIDLIST pidl = NULL;
// Make item ID list from leading path
hResult = SHGetIDListFromPath( hwndOwner, pszPathCopy, &pidl );
// if path exists try to open it as folder
if ( SUCCEEDED(hResult) )
{
// Only open the folder if it was not the last token
if ( pszTrailingPath )
{
LPSHELLFOLDER pFolder;
// Create a folder instance
hResult = SHGetFolderFromIDList( pidl, &pFolder);
// Is it a folder ?
if ( SUCCEEDED(hResult) )
{
// No try to instantiate an enumerator.
// This should popup a login dialog if any
LPENUMIDLIST pEnum = NULL;
hResult = pFolder->EnumObjects( hwndOwner,
SHCONTF_NONFOLDERS | SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN,
&pEnum );
// Release the enumerator interface
if ( SUCCEEDED(hResult) )
pEnum->Release();
// Release the folder interface
pFolder->Release();
}
SHFreeMem( pidl );
}
else // It was the last token
{
if ( ppidl )
*ppidl = pidl;
else
SHFreeMem( pidl );
}
}
// Forward to next token
if ( pszTrailingPath )
{
*pszTrailingPath = cBackup;
pszTrailingPath = lstrchr( pszTrailingPath, '\\' );
}
else
break;
}
// Free the working copy of the path
delete pszPathCopy;
// NOERROR or OLE error code
return hResult;
#endif
}
//---------------------------------------------------------------------------
// The Wrapper
//---------------------------------------------------------------------------
sal_Bool Exists_Impl( const ByteString & crPath )
{
// We do not know if OLE was initialized for this thread
CoInitialize( NULL );
sal_Bool bSuccess = SUCCEEDED( SHResolvePath(NULL, crPath.GetBuffer(), NULL) );
CoUninitialize();
return bSuccess;
}
//---------------------------------------------------------------------------
sal_Bool FileStat::Update( const DirEntry& rDirEntry, sal_Bool bForceAccess )
{
nSize = 0;
nKindFlags = 0;
aCreator.Erase();
aType.Erase();
aDateCreated = Date(0);
aTimeCreated = Time(0);
aDateModified = Date(0);
aTimeModified = Time(0);
aDateAccessed = Date(0);
aTimeAccessed = Time(0);
if ( !rDirEntry.IsValid() )
{
nError = FSYS_ERR_UNKNOWN;
nKindFlags = 0;
return sal_False;
}
// Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt
if ( !rDirEntry.aName.Len() && rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
{
nKindFlags = FSYS_KIND_DIR;
nError = FSYS_ERR_OK;
return sal_True;
}
// keine Error-Boxen anzeigen
FSysFailOnErrorImpl();
// Redirect
String aPath( rDirEntry.GetFull() );
#ifndef BOOTSTRAP
FSysRedirector::DoRedirect( aPath );
#endif
DirEntry aDirEntry( aPath );
// ist ein Medium im Laufwerk?
HACK("wie?")
sal_Bool bAccess = sal_True;
const DirEntry *pTop = aDirEntry.ImpGetTopPtr();
ByteString aName = ByteString(pTop->aName).ToLowerAscii();
if ( !bForceAccess &&
( pTop->eFlag == FSYS_FLAG_ABSROOT ||
pTop->eFlag == FSYS_FLAG_RELROOT ||
pTop->eFlag == FSYS_FLAG_VOLUME ) )
if ( aName == "a:" || aName == "b:" )
bAccess = sal_False;
else
DBG_TRACE( "FSys: will access removable device!" );
if ( bAccess && ( aName == "a:" || aName == "b:" ) ) {
DBG_WARNING( "floppy will clatter" );
}
// Sonderbehandlung, falls es sich um ein Volume handelt
if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ||
aDirEntry.eFlag == FSYS_FLAG_ABSROOT )
{
if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
nKindFlags = FSYS_KIND_DEV | ( aDirEntry.aName.Len() == 2
? FSYS_KIND_BLOCK
: FSYS_KIND_CHAR );
else
nKindFlags = FSYS_KIND_DIR;
if ( !bAccess )
{
if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
nKindFlags |= FSYS_KIND_REMOVEABLE;
nError = FSYS_ERR_NOTEXISTS;
nKindFlags = 0;
return sal_False;
}
ByteString aRootDir = aDirEntry.aName;
aRootDir += ByteString( "\\" );
UINT nType = GetDriveType( (char *) aRootDir.GetBuffer() ); //TPF: 2i
if ( nType == 1 || nType == 0 )
{
nError = FSYS_ERR_NOTEXISTS;
nKindFlags = 0;
return sal_False;
}
if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
nKindFlags = nKindFlags |
( ( nType == DRIVE_REMOVABLE ) ? FSYS_KIND_REMOVEABLE : 0 ) |
( ( nType == DRIVE_FIXED ) ? FSYS_KIND_FIXED : 0 ) |
( ( nType == DRIVE_REMOTE ) ? FSYS_KIND_REMOTE : 0 ) |
( ( nType == DRIVE_RAMDISK ) ? FSYS_KIND_RAM : 0 ) |
( ( nType == DRIVE_CDROM ) ? FSYS_KIND_CDROM : 0 ) |
( ( nType == 0 ) ? FSYS_KIND_UNKNOWN : 0 );
nError = ERRCODE_NONE;
return sal_True;
}
// Statusinformation vom Betriebssystem holen
HANDLE h; //()
_WIN32_FIND_DATAA aEntry = {};
DirEntry aAbsEntry( aDirEntry );
if ( bAccess && aAbsEntry.ToAbs() )
{
// im Namen k"onnen auch ';*?' als normale Zeichen vorkommen
ByteString aFilePath( aAbsEntry.GetFull(), osl_getThreadTextEncoding() );
// MI: dann gehen Umlaute auf Novell-Servern nicht / wozu ueberhaupt
// CharUpperBuff( (char*) aFilePath.GetStr(), aFilePath.Len() );
DBG_TRACE1( "FileStat: %s", aFilePath.GetBuffer() );
h = aFilePath.Len() < 230
// die Win32-API ist hier sehr schwammig
? FindFirstFile( (char *) aFilePath.GetBuffer(), &aEntry )//TPF: 2i
: INVALID_HANDLE_VALUE;
if ( INVALID_HANDLE_VALUE != h )
{
if ( !( aEntry.dwFileAttributes & 0x40 ) ) // com1: etc. e.g. not encrypted (means normal)
{
ByteString aUpperName = Upper_Impl(ByteString(aAbsEntry.GetName(), osl_getThreadTextEncoding()));
// HRO: #74051# Compare also with short alternate filename
if ( aUpperName != Upper_Impl( aEntry.cFileName ) && aUpperName != Upper_Impl( aEntry.cAlternateFileName ) )
h = INVALID_HANDLE_VALUE;
}
}
if ( INVALID_HANDLE_VALUE == h )
{
DWORD dwError = GetLastError();
if ( ERROR_BAD_NET_NAME == dwError )
{
nKindFlags = FSYS_KIND_UNKNOWN;
nError = FSYS_ERR_NOTEXISTS;
return sal_False;
}
// UNC-Volume?
DirEntry *pTop = aAbsEntry.ImpGetTopPtr();
if ( pTop->GetFlag() == FSYS_FLAG_ABSROOT &&
( pTop->aName.Len() > 1 && (pTop->aName.GetBuffer()[1] != ':' )) )
{
if ( bForceAccess )
{
if ( Exists_Impl( aFilePath ) )
{
nKindFlags = FSYS_KIND_DIR|FSYS_KIND_REMOTE;
nError = FSYS_ERR_OK;
return sal_True;
}
else
{
nKindFlags = FSYS_KIND_UNKNOWN;
nError = FSYS_ERR_NOTEXISTS;
return sal_False;
}
}
}
}
}
else
h = INVALID_HANDLE_VALUE;
if ( h == INVALID_HANDLE_VALUE )
{
// Sonderbehandlung falls es sich um eine Wildcard handelt
ByteString aTempName( aDirEntry.GetName(), osl_getThreadTextEncoding() );
if ( strchr( aTempName.GetBuffer(), '?' ) ||
strchr( aTempName.GetBuffer(), '*' ) ||
strchr( aTempName.GetBuffer(), ';' ) )
{
nKindFlags = FSYS_KIND_WILD;
nError = FSYS_ERR_OK;
return sal_True;
}
if ( bAccess )
{
nError = FSYS_ERR_NOTEXISTS;
nKindFlags = FSYS_KIND_UNKNOWN;
}
else
nKindFlags = FSYS_KIND_REMOVEABLE;
}
else
{
ImpInit( &aEntry );
FindClose( h );
}
if ( 0 != nError )
nKindFlags = 0;
return 0 == nError;
}
sal_Bool IsRedirectable_Impl( const ByteString &rPath )
{
if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] )
{
ByteString aVolume = rPath.Copy( 0, 3 );
UINT nType = GetDriveType( (char *) aVolume.GetBuffer() );
SetLastError( ERROR_SUCCESS );
return DRIVE_FIXED != nType;
}
return sal_False;
}
/*************************************************************************
|*
|* TempDirImpl()
|*
|* Beschreibung liefert den Namens des Directories fuer temporaere
|* Dateien
|* Ersterstellung MI 16.03.94
|* Letzte Aenderung MI 16.03.94
|*
*************************************************************************/
const char* TempDirImpl( char *pBuf )
{
if ( !GetTempPath( MAX_PATH, pBuf ) &&
!GetWindowsDirectory( pBuf, MAX_PATH ) &&
!GetEnvironmentVariable( "HOMEPATH", pBuf, MAX_PATH ) )
return 0;
return pBuf;
}
//=======================================================================
ErrCode FileStat::QueryDiskSpace( const String &rPath,
BigInt &rFreeBytes, BigInt &rTotalBytes )
{
DWORD nSectorsPerCluster; /* address of sectors per cluster */
DWORD nBytesPerSector; /* address of bytes per sector */
DWORD nFreeClusters; /* address of number of free clusters */
DWORD nClusters; /* address of total number of clusters */
ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding());
bool bOK = GetDiskFreeSpace( aVol.GetBuffer(),
&nSectorsPerCluster, &nBytesPerSector,
&nFreeClusters, &nClusters );
if ( !bOK )
return Sys2SolarError_Impl( GetLastError() );
BigInt aBytesPerCluster( BigInt(nSectorsPerCluster) *
BigInt(nBytesPerSector) );
rFreeBytes = aBytesPerCluster * BigInt(nFreeClusters);
rTotalBytes = aBytesPerCluster * BigInt(nClusters);
return 0;
}
//=========================================================================
void FSysEnableSysErrorBox( sal_Bool bEnable )
{ // Preserve other Bits!!
sal_uInt32 nErrorMode = SetErrorMode( bEnable ? 0 : SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX );
if ( bEnable )
nErrorMode &= ~(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
else
nErrorMode |= (SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
SetErrorMode( nErrorMode );
}