blob: 587fc6aeef46acc9640835fb1c463cfca5aaaf2e [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.
*
*************************************************************/
#define INCL_DOSEXCEPTIONS
#include <stdlib.h>
#ifdef __BORLANDC__
#include <alloc.h>
#else
#include <malloc.h>
#endif
#include <tools/debug.hxx>
#include <tools/list.hxx>
#include <tools/bigint.hxx>
#include <tools/fsys.hxx>
#include "comdep.hxx"
#ifdef OS2
#ifndef _VOS_MUTEX_HXX //autogen
#include <vos/mutex.hxx>
#endif
#endif
int Sys2SolarError_Impl( int nSysErr );
DECLARE_LIST( DirEntryList, DirEntry* );
DECLARE_LIST( FSysSortList, FSysSort* );
DECLARE_LIST( FileStatList, FileStat* );
static char sCaseMap[256];
static sal_Bool bCaseMap = FALSE;
static sal_Bool bDriveMap = FALSE;
struct DriveMapItem
{
DirEntryKind nKind;
char cName;
FSysPathStyle nStyle;
};
void CreateCaseMapImpl();
void CreateDriveMapImpl();
static DriveMapItem aDriveMap[26];
static sal_Bool bLastCaseSensitive = FALSE;
//====================================================================
int ApiRet2ToSolarError_Impl( int nApiRet )
{
switch ( nApiRet )
{
case NO_ERROR: return ERRCODE_NONE;
case ERROR_FILE_NOT_FOUND: return ERRCODE_IO_NOTEXISTS;
case ERROR_PATH_NOT_FOUND: return ERRCODE_IO_NOTEXISTSPATH;
case ERROR_TOO_MANY_OPEN_FILES: return ERRCODE_IO_TOOMANYOPENFILES;
case ERROR_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED;
case ERROR_NOT_ENOUGH_MEMORY: return ERRCODE_IO_OUTOFMEMORY;
case ERROR_BAD_FORMAT: return ERRCODE_IO_WRONGFORMAT;
case ERROR_NOT_SAME_DEVICE: return ERRCODE_IO_INVALIDDEVICE;
case ERROR_WRITE_PROTECT: return ERRCODE_IO_INVALIDDEVICE;
case ERROR_BAD_UNIT: return ERRCODE_IO_INVALIDDEVICE;
case ERROR_CRC: return ERRCODE_IO_INVALIDDEVICE;
case ERROR_NOT_DOS_DISK: return ERRCODE_IO_INVALIDDEVICE;
case ERROR_WRITE_FAULT: return ERRCODE_IO_CANTWRITE;
case ERROR_READ_FAULT: return ERRCODE_IO_CANTREAD;
case ERROR_SHARING_VIOLATION: return ERRCODE_IO_LOCKVIOLATION;
case ERROR_LOCK_VIOLATION: return ERRCODE_IO_LOCKVIOLATION;
case ERROR_WRONG_DISK: return ERRCODE_IO_LOCKVIOLATION;
case ERROR_HANDLE_DISK_FULL: return ERRCODE_IO_OUTOFSPACE;
case ERROR_NOT_SUPPORTED: return ERRCODE_IO_NOTSUPPORTED;
case ERROR_DUP_NAME: return ERRCODE_IO_ALREADYEXISTS;
case ERROR_BAD_NETPATH: return ERRCODE_IO_NOTEXISTSPATH;
case ERROR_DEV_NOT_EXIST: return ERRCODE_IO_NOTEXISTS;
case ERROR_NETWORK_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED;
case ERROR_INVALID_PARAMETER: return ERRCODE_IO_INVALIDPARAMETER;
case ERROR_NET_WRITE_FAULT: return ERRCODE_IO_CANTWRITE;
case ERROR_DEVICE_IN_USE: return ERRCODE_IO_INVALIDPARAMETER;
case ERROR_DISK_FULL: return ERRCODE_IO_OUTOFSPACE;
case ERROR_BAD_ARGUMENTS: return ERRCODE_IO_INVALIDPARAMETER;
case ERROR_BAD_PATHNAME: return ERRCODE_IO_NOTEXISTSPATH;
case ERROR_LOCK_FAILED: return ERRCODE_IO_LOCKVIOLATION;
case ERROR_LOCKED: return ERRCODE_IO_LOCKVIOLATION;
case ERROR_DUPLICATE_NAME: return ERRCODE_IO_ALREADYEXISTS;
case ERROR_DIRECTORY_IN_CDS: return ERRCODE_IO_LOCKVIOLATION;
case ERROR_CURRENT_DIRECTORY: return ERRCODE_IO_LOCKVIOLATION;
case ERROR_FILENAME_EXCED_RANGE: return ERRCODE_IO_NAMETOOLONG;
}
DBG_TRACE1( "FSys: unknown apiret error %d occured", nApiRet );
return FSYS_ERR_UNKNOWN;
}
//--------------------------------------------------------------------
char* volumeid( const char* pPfad )
{
static FSINFO aFSInfoBuf;
ULONG ulFSInfoLevel = FSIL_VOLSER;
ULONG nDriveNumber;
nDriveNumber = toupper(*pPfad) - 'A' + 1;
if ( nDriveNumber >= 3 )
{
APIRET rc = DosQueryFSInfo(
nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) );
if ( rc )
return 0;
return (char*) aFSInfoBuf.vol.szVolLabel;
}
return 0;
}
//--------------------------------------------------------------------
/*************************************************************************
|*
|* DirEntry::ToAbs()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 26.04.91
|* Letzte Aenderung MA 02.12.91 13:30
|*
*************************************************************************/
sal_Bool DirEntry::ToAbs()
{
DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
if ( FSYS_FLAG_VOLUME == eFlag )
{
eFlag = FSYS_FLAG_ABSROOT;
return TRUE;
}
if ( IsAbs() )
return TRUE;
char sBuf[_MAX_PATH + 1];
*this = DirEntry( String( getcwd( sBuf, _MAX_PATH ), osl_getThreadTextEncoding() ) ) + *this;
return IsAbs();
}
/*************************************************************************
|*
|* DirEntry::GetVolume()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 04.03.92
|* Letzte Aenderung MI 04.03.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() )
{
const char *pVol;
pVol = volumeid( (char*) pTop->aName.GetBuffer() );
if (pVol)
aRet = String( pVol, 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 );
if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() )
return TRUE;
if ( !chdir(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
{
//nError = FSYS_ERR_OK;
return TRUE;
}
if ( bSloppy && pParent &&
!chdir(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
{
//nError = FSYS_ERR_OK;
return TRUE;
}
//nError = FSYS_ERR_NOTADIRECTORY;
return FALSE;
}
/*************************************************************************
|*
|* DirEntry::MoveTo()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 26.04.91
|* Letzte Aenderung MA 02.12.91 14:07
|*
*************************************************************************/
#if 0 // YD see dirent.cxx
sal_Bool createLongNameEA( const PCSZ pszPath, ULONG ulAttributes, const String& aLongName );
FSysError DirEntry::MoveTo( const DirEntry& rDest ) const
{
DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
DirEntry aTmpDest(rDest);
FileStat aTmpStat(aTmpDest);
if ( aTmpStat.IsKind(FSYS_KIND_DIR) )
aTmpDest += DirEntry( GetName() );
String aSource( GetFull() );
String aDest( aTmpDest.GetFull() );
String aShortSource("");
String aShortDest("");
if (Folder::IsAvailable())
{
if (IsLongNameOnFAT())
{
// in kurzen Pfad wandeln
ItemIDPath aItemIDPath(aSource);
aShortSource = aItemIDPath.GetHostNotationPath();
}
if (rDest.IsLongNameOnFAT())
{
// in kurzen Pfad wandeln
ItemIDPath aItemIDPath(aDest);
aShortDest = aItemIDPath.GetHostNotationPath();
}
}
APIRET nRet = DosMove( aShortSource.Len()>0?(PSZ)aShortSource.GetStr():(PSZ)aSource.GetStr(),
aShortDest.Len()>0?(PSZ)aShortDest.GetStr():(PSZ)aDest.GetStr());
if ( nRet == ERROR_DIRECTORY_IN_CDS ||
nRet == ERROR_CURRENT_DIRECTORY )
{
// 2nd chance with modified CWD
DosSetCurrentDir( (PSZ) "\\" );
nRet = DosMove( aShortSource.Len()>0?(PSZ)aShortSource.GetStr():(PSZ)aSource.GetStr(),
aShortDest.Len()>0?(PSZ)aShortDest.GetStr():(PSZ)aDest.GetStr());
}
else if ( nRet == ERROR_NOT_SAME_DEVICE )
{
// other volume => copy+delete
FileCopier aMover( *this, rDest );
nRet = aMover.Execute( FSYS_ACTION_MOVE|FSYS_ACTION_RECURSIVE );
return nRet;
}
if ( (nRet==NO_ERROR) && aShortDest.Len()>0)
{
createLongNameEA((const char*)aShortDest, FILE_NORMAL, rDest.GetName());
}
return ApiRet2ToSolarError_Impl( nRet );
}
#endif // 0
//-------------------------------------------------------------------------
USHORT DirReader_Impl::Init()
{
// Block-Devices auflisten?
if ( pDir->eAttrMask & FSYS_KIND_BLOCK )
{
CreateDriveMapImpl();
// 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()))
&& aDriveMap[c-'a'].nKind != FSYS_KIND_UNKNOWN )
{
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()
{
if (!pDosDir)
{
pDosDir = opendir( (char*) ByteString(aPath, osl_getThreadTextEncoding()).GetBuffer() );
}
if (!pDosDir)
{
bReady = TRUE;
return 0;
}
// Directories und Files auflisten?
if ( ( pDir->eAttrMask & FSYS_KIND_DIR || pDir->eAttrMask & FSYS_KIND_FILE ) &&
( ( pDosEntry = readdir( pDosDir ) ) != NULL ) )
{
String aD_Name(pDosEntry->d_name, osl_getThreadTextEncoding());
if ( pDir->aNameMask.Matches( aD_Name ) )
{
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_UNX );
if ( pParent )
pTemp->ImpChangeParent( new DirEntry( *pParent ), FALSE);
FileStat aStat( *pTemp );
if ( ( ( ( pDir->eAttrMask & FSYS_KIND_DIR ) &&
( aStat.IsKind( FSYS_KIND_DIR ) ) ) ||
( ( pDir->eAttrMask & FSYS_KIND_FILE ) &&
!( aStat.IsKind( FSYS_KIND_DIR ) ) ) ) &&
!( pDir->eAttrMask & FSYS_KIND_VISIBLE &&
pDosEntry->d_name[0] == '.' ) )
{
if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
pDir->ImpSortedInsert( pTemp, new FileStat( aStat ) );
else
pDir->ImpSortedInsert( pTemp, NULL );;
return 1;
}
else
delete pTemp;
}
}
else
bReady = TRUE;
return 0;
}
/*************************************************************************
|*
|* FileStat::FileStat()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MA 05.11.91
|* Letzte Aenderung MA 07.11.91
|*
*************************************************************************/
FileStat::FileStat( const void *pInfo, // struct dirent
const void * ): // dummy
aDateCreated(0),
aTimeCreated(0),
aDateModified(0),
aTimeModified(0),
aDateAccessed(0),
aTimeAccessed(0)
{
struct dirent *pDirent = (struct dirent*) pInfo;
nSize = pDirent->d_size;
aDateCreated = MsDos2Date( (FDATE*) &pDirent->d_date );
aTimeCreated = MsDos2Time( (FTIME*) &pDirent->d_time );
aDateModified = aDateModified;
aTimeModified = aTimeModified;
aDateAccessed = aDateModified;
aTimeAccessed = aTimeModified;
nKindFlags = FSYS_KIND_FILE;
if ( pDirent->d_type & DOS_DIRECT )
nKindFlags = FSYS_KIND_DIR;
}
/*************************************************************************
|*
|* FileStat::Update()
|*
|* Beschreibung FSYS.SDW
|* Ersterstellung MI 11.06.91
|* Letzte Aenderung MA 07.11.91
|*
*************************************************************************/
struct _FSYS_FSQBUFFER
{
FSQBUFFER2 aBuf;
UCHAR sBuf[256];
};
sal_Bool FileStat::Update( const DirEntry& rDirEntry, sal_Bool bAccessRemovableDevice )
{
nSize = 0;
FSysPathStyle eStyle = FSYS_STYLE_UNKNOWN;
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_NOTEXISTS;
return 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 TRUE;
}
// Sonderbehandlung falls es sich um eine Wildcard handelt
ByteString aTempName( rDirEntry.GetName(), osl_getThreadTextEncoding() );
if ( strchr( aTempName.GetBuffer(), '?' ) ||
strchr( aTempName.GetBuffer(), '*' ) ||
strchr( aTempName.GetBuffer(), ';' ) )
{
nKindFlags = FSYS_KIND_WILD;
nError = FSYS_ERR_OK;
return TRUE;
}
// Sonderbehandlung falls es sich um eine Root handelt
if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME ||
rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
{
if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME )
nKindFlags = FSYS_KIND_DEV;
else
nKindFlags = FSYS_KIND_DIR;
if ( rDirEntry.aName.Len() == 2 )
{
if ( !bDriveMap )
CreateDriveMapImpl();
ByteString rDirEntryUpperCase = ByteString( rDirEntry.aName ).ToUpperAscii();
DriveMapItem &rItem = aDriveMap[rDirEntryUpperCase.GetChar(0) - 'A'];
if ( !rItem.nKind )
{
nError = ERRCODE_IO_INVALIDDEVICE;
nKindFlags = FSYS_KIND_UNKNOWN;
return FALSE;
}
else
{
if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME )
nKindFlags |= FSYS_KIND_BLOCK | rItem.nKind;
eStyle = rItem.nStyle;
}
}
nError = FSYS_ERR_OK;
return TRUE;
}
// disable error-boxes for hard-errors
DosError(FERR_DISABLEHARDERR);
// Statusinformation vom Betriebssystem holen
DirEntry aTempDirEntry( rDirEntry );
char* p;
aTempDirEntry.ToAbs();
ByteString aFullName( aTempDirEntry.GetFull(), osl_getThreadTextEncoding() );
#if 0 // YD
if (Folder::IsAvailable() && aTempDirEntry.IsLongNameOnFAT())
{
// in String mit kurzem Pfad wandeln
ItemIDPath aItemIDPath(aTempDirEntry.GetFull());
aFullName = ByteString( aItemIDPath.GetHostNotationPath(), osl_getThreadTextEncoding() );
}
#endif
p = (char *) aFullName.GetBuffer();
FILESTATUS3 filestat;
memset( &filestat, 0, sizeof( filestat ) );
if( DosQueryPathInfo( (PSZ)p, 1, &filestat, sizeof( filestat ) ) )
{
nError = FSYS_ERR_NOTEXISTS;
nKindFlags = FSYS_KIND_UNKNOWN;
return FALSE;
}
nError = FSYS_ERR_OK;
nSize = filestat.cbFile;
nKindFlags = FSYS_KIND_UNKNOWN;
if( filestat.attrFile & FILE_DIRECTORY )
nKindFlags |= FSYS_KIND_DIR;
if ( nKindFlags == FSYS_KIND_UNKNOWN )
nKindFlags = nKindFlags | FSYS_KIND_FILE;
aDateModified = Date( filestat.fdateLastWrite.day,
filestat.fdateLastWrite.month,
filestat.fdateLastWrite.year + 1980 );
aTimeModified = Time( filestat.ftimeLastWrite.hours,
filestat.ftimeLastWrite.minutes,
filestat.ftimeLastWrite.twosecs*2 );
if ( filestat.fdateCreation.day )
{
aDateCreated = Date( filestat.fdateCreation.day,
filestat.fdateCreation.month,
filestat.fdateCreation.year + 1980 );
aTimeCreated = Time( filestat.ftimeCreation.hours,
filestat.ftimeCreation.minutes,
filestat.ftimeCreation.twosecs*2 );
}
else
{
aDateCreated = aDateModified;
aTimeCreated = aTimeModified;
}
if ( filestat.fdateLastAccess.day > 0 )
{
aDateAccessed = Date( filestat.fdateLastAccess.day,
filestat.fdateLastAccess.month,
filestat.fdateLastAccess.year + 1980 );
aTimeAccessed = Time( filestat.ftimeLastAccess.hours,
filestat.ftimeLastAccess.minutes,
filestat.ftimeLastAccess.twosecs*2 );
}
else
{
aDateAccessed = aDateModified;
aTimeAccessed = aTimeModified;
}
return TRUE;
}
sal_Bool IsRedirectable_Impl( const ByteString &rPath )
{
if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] )
{
ByteString aVolume = rPath.Copy( 0, 3 );
DriveMapItem &rItem = aDriveMap[toupper(aVolume.GetChar(0)) - 'A'];
return FSYS_KIND_FIXED != rItem.nKind;
}
return FALSE;
}
#if 0
sal_Bool IsRedirectable_Impl( const String &rPath )
{
if ( rPath.Len() >= 3 && ':' == rPath.GetStr()[1] )
{
DriveMapItem &rItem = aDriveMap[toupper(rPath[0]) - 'A'];
return FSYS_KIND_FIXED != rItem.nKind;
}
return FALSE;
}
#endif
/*************************************************************************
|*
|* 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 )
{
PSZ pVar;
USHORT nRet;
sal_Bool bAppendTemp = FALSE; // mu\s noch \\temp angeh"angt werden
// Erstmal sehen, ob TEMP oder TMP gesetzt sind
nRet = DosScanEnv( (PSZ)"TEMP", &pVar );
if( nRet )
nRet = DosScanEnv( (PSZ)"temp", &pVar );
if( nRet )
nRet = DosScanEnv( (PSZ)"TMP", &pVar );
if( nRet )
nRet = DosScanEnv( (PSZ)"tmp", &pVar );
if( nRet )
nRet = DosScanEnv( (PSZ)"TMPDIR", &pVar );
// falls das geklappt hat, und ein Backslash dranhaengt,
// oder falls es bisher nicht geklappt hat,
// muessen wir nachher einen Backslash entfernen
sal_Bool bRemoveBS = nRet || *(pVar+strlen(pVar)-1) == '\\';
// Keine temp-Variable gefunden, dann gehen wir mal auf die Suche
// nach dem System-Laufwerk
if( nRet )
{
nRet = DosScanEnv( (PSZ)"USER_INI",&pVar );
bAppendTemp = (0 == nRet);
}
if( nRet )
{
nRet = DosScanEnv( (PSZ)"SYSTEM_INI", &pVar );
bAppendTemp = (0 == nRet);
}
if( nRet )
// Wenn das immer noch nicht reicht nehmen wir eben die Root von C:
#ifdef __BORLANDC__
pVar = (PSZ)"c:\\temp\\";
#else
pVar = (PCSZ)"c:\\temp\\";
#endif
strcpy( pBuf, (const char*)pVar );
// jetzt haengt ggf. ein Backlash dran, den wir abschneiden,
// ggf. inklusive dahinter haengendem Dateinamen
if ( bRemoveBS )
{
char *pTail = pBuf + strlen(pBuf) - 1;
for ( char cLast = *pTail; cLast != '\\'; cLast = *(--pTail) )
*pTail = 0;
}
if ( bAppendTemp )
strcat( pBuf, "\\temp" );
DirEntry( pBuf ).MakeDir();
return pBuf;
}
#define CURRENT_COUNTRY 0
#define NLS_CODEPAGE 850
/*====================================================================
* CreateCaseMapImpl()
* creates a map of each character to convert to lower
*--------------------------------------------------------------------*/
#if 0
void CreateCaseMapImpl()
{
// build a string starting with code 0 as first character upto 255
char sTemp[256];
USHORT n;
for ( n = 0; n < 256; ++n )
sTemp[n] = (char) n;
// convert string to upper case
COUNTRYCODE aCountry;
aCountry.country = CURRENT_COUNTRY; /* Country code */
aCountry.codepage = NLS_CODEPAGE; /* Code page */
DosMapCase( 255, &aCountry, sTemp+1 );
// fill a global buffer starting with code 0 as first character upto 255
for ( n = 0; n < 256; ++n )
sCaseMap[n] = (char) n;
// reorder by upper-code and store in a global buffer
for ( n = 255; n > 0; --n )
// was this character converted?
if ( sTemp[n] != (char) n )
// we found a convertion from upper to lower
sCaseMap[ (unsigned char) sTemp[n] ] = (char) n;
bCaseMap = TRUE;
}
String ToLowerImpl( const String& rSource )
{
if ( !bCaseMap )
CreateCaseMapImpl();
// TH sagt: International ist zu langsam, also mit einer eigenen Map
ByteString aLower( rSource );
for ( USHORT n = 0; n < aLower.Len(); ++n )
aLower[n] = sCaseMap[ (unsigned char) aLower[n] ];
return aLower;
}
#endif // 0
/*====================================================================
* CreateDriveMapImpl()
* creates a map of drive-infos like FileSystem (style) and Kind (remote)
*--------------------------------------------------------------------*/
typedef struct _FSQBUFFER_
{
FSQBUFFER2 aBuf;
UCHAR sBuf[64];
} FSQBUFFER_;
void CreateDriveMapImpl()
{
#ifdef POWERPC
// !!!!! Hack, da der untere Teil mit Beta 2 noch abstuertzt !!!!!
BYTE nFloppies = 1;
for ( USHORT nDrive = 0; nDrive < 26; ++nDrive )
{
if ( nDrive < nFloppies )
{
aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE;
aDriveMap[nDrive].nStyle = FSYS_STYLE_FAT;
}
else
{
aDriveMap[nDrive].nKind = FSYS_KIND_UNKNOWN;
aDriveMap[nDrive].nStyle = FSYS_STYLE_UNKNOWN;
}
}
aDriveMap[2].nKind = FSYS_KIND_FIXED;
aDriveMap[2].nStyle = FSYS_STYLE_FAT;
#else
FSQBUFFER_ aBuf;
ULONG nBufLen;
APIRET nRet;
USHORT nDrive;
// disable error-boxes for hard-errors
DosError(FERR_DISABLEHARDERR);
// determine number of floppy-drives
PM_BYTE nFloppies;
nRet = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
// reset the map
for ( nDrive = 0; nDrive < 26; ++nDrive )
{
if ( nDrive < nFloppies )
{
aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE;
aDriveMap[nDrive].nStyle = FSYS_STYLE_FAT;
}
else
{
aDriveMap[nDrive].nKind = FSYS_KIND_UNKNOWN;
aDriveMap[nDrive].nStyle = FSYS_STYLE_UNKNOWN;
}
}
// determine file-system via DosOpen/DocDevIOCtrl
for ( nDrive = 2; nDrive < 26; ++nDrive )
{
// open drive
sal_Bool bFixed;
HFILE nDevHandle;
char pDriveName[3] = "#:";
pDriveName[0] = nDrive+'a';
ULONG nAction;
nRet = DosOpen( (PSZ) pDriveName, &nDevHandle,
&nAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_FLAGS_DASD|OPEN_SHARE_DENYNONE|OPEN_ACCESS_READONLY,
0 );
// exists?
if ( !nRet )
{
// removeable?
PM_BYTE nDriveId = nDrive;
ULONG nParaOutLen, nDataOutLen;
nRet = DosDevIOCtl(nDevHandle, 8, 0x20,
&nDriveId, sizeof(nDriveId), &nParaOutLen,
&bFixed, sizeof(bFixed), &nDataOutLen );
// prepare the drive-map
if ( !nRet && !bFixed )
aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE;
// close drive
DosClose(nDevHandle);
}
else if ( nRet == ERROR_NOT_READY )
aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE | FSYS_KIND_CDROM;
}
// determine file-system via FSAttach
nRet = 0;
for ( USHORT n = 3; nRet != ERROR_NO_MORE_ITEMS; ++n )
{
nBufLen = sizeof( aBuf );
nRet = DosQueryFSAttach( 0, n, FSAIL_DRVNUMBER,
(_FSQBUFFER2*) &aBuf, &nBufLen );
if ( !nRet )
{
nDrive = toupper(aBuf.aBuf.szName[0]) - 'A';
if ( aDriveMap[nDrive].nKind == FSYS_KIND_UNKNOWN )
aDriveMap[nDrive].nKind =
aBuf.aBuf.iType == 3 ? FSYS_KIND_FIXED :
aBuf.aBuf.iType == 4 ? FSYS_KIND_REMOTE :
FSYS_KIND_UNKNOWN;
char *pType = (char*)(aBuf.aBuf.szName + aBuf.aBuf.cbName + 1);
aDriveMap[nDrive].nStyle =
strcmp( pType, "FAT" ) == 0 ? FSYS_STYLE_FAT :
strcmp( pType, "FAT32" ) == 0 ? FSYS_STYLE_VFAT :
strcmp( pType, "NTFS" ) == 0 ? FSYS_STYLE_NTFS :
strcmp( pType, "HPFS" ) == 0 ? FSYS_STYLE_HPFS :
strcmp( pType, "JFS" ) == 0 ? FSYS_STYLE_HPFS :
strcmp( pType, "RAMFS" ) == 0 ? FSYS_STYLE_HPFS :
strcmp( pType, "NDFS32" ) == 0 ? FSYS_STYLE_HPFS :
strcmp( pType, "NWFS" ) == 0 ? FSYS_STYLE_NWFS :
strcmp( pType, "EXT2" ) == 0 ? FSYS_STYLE_UNX :
strcmp( pType, "NFS" ) == 0 ? FSYS_STYLE_UNX :
FSYS_STYLE_UNKNOWN;
if ( strcmp( pType, "CDFS" ) == 0 )
aDriveMap[nDrive].nKind = FSYS_KIND_CDROM|FSYS_KIND_REMOVEABLE;
}
}
#endif
bDriveMap = TRUE;
}
Time MsDos2Time( const time_t *pTimeT )
{
tm *pTm = localtime( pTimeT );
if ( pTm )
return Time( pTm->tm_hour, pTm->tm_min, pTm->tm_sec );
else
return Time(0);
}
Date MsDos2Date( const time_t *pTimeT )
{
tm *pTm = localtime( pTimeT );
if ( pTm )
return Date( pTm->tm_mday, pTm->tm_mon + 1, pTm->tm_year );
else
return Date(0);
}
/*************************************************************************
|*
|* DirEntry::GetPathStyle() const
|*
|* Beschreibung
|* Ersterstellung MI 11.05.95
|* Letzte Aenderung MI 11.05.95
|*
*************************************************************************/
FSysPathStyle DirEntry::GetPathStyle( const String &rDevice )
{
ByteString aRootDir(rDevice, osl_getThreadTextEncoding());
// UNC-Pathname?
if ( aRootDir.Len()==0 || ( aRootDir.Len() > 1 && aRootDir.GetChar(1) != ':' ) )
return FSYS_STYLE_UNKNOWN;
if ( !bDriveMap )
CreateDriveMapImpl();
return aDriveMap[toupper(aRootDir.GetChar(0)) - 'A'].nStyle;
}
/*************************************************************************
|*
|* DirEntry::IsCaseSensitive() const
|*
|* Beschreibung
|* Ersterstellung TPF 26.02.1999
|* Letzte Aenderung
|*
*************************************************************************/
sal_Bool DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
{
if (eFormatter==FSYS_STYLE_HOST)
{
if (GetPathStyle(GetDevice().GetName()) == FSYS_STYLE_UNX)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
sal_Bool isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall 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 = FALSE;
break;
}
case FSYS_STYLE_SYSV:
case FSYS_STYLE_BSD:
{
isCaseSensitive = TRUE;
break;
}
default:
{
isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv
break;
}
}
return isCaseSensitive;
}
}
//=========================================================================
ErrCode FileStat::QueryDiskSpace( const String &rPath,
BigInt &rFreeBytes, BigInt &rTotalBytes )
{
FSALLOCATE aFSInfoBuf;
ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding());
ULONG nDriveNumber = toupper( aVol.GetChar(0) ) - 'A' + 1;
APIRET rc = DosQueryFSInfo( nDriveNumber, FSIL_ALLOC,
&aFSInfoBuf, sizeof(aFSInfoBuf) );
if ( rc )
return Sys2SolarError_Impl( rc );
BigInt aBytesPerCluster( BigInt(aFSInfoBuf.cbSector) *
BigInt(aFSInfoBuf.cSectorUnit) );
rFreeBytes = aBytesPerCluster * BigInt(aFSInfoBuf.cUnitAvail);
rTotalBytes = aBytesPerCluster * BigInt(aFSInfoBuf.cUnit);
return 0;
}
//=========================================================================
void FSysEnableSysErrorBox( sal_Bool bEnable )
{
DosError( bEnable ? 0 : FERR_DISABLEHARDERR );
}