1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: os2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #define INCL_DOSEXCEPTIONS
40 #include <tools/debug.hxx>
41 #include <tools/list.hxx>
42 #include <tools/bigint.hxx>
43 #include <tools/fsys.hxx>
47 #ifndef _VOS_MUTEX_HXX //autogen
48 #include <vos/mutex.hxx>
52 int Sys2SolarError_Impl( int nSysErr
);
54 DECLARE_LIST( DirEntryList
, DirEntry
* );
55 DECLARE_LIST( FSysSortList
, FSysSort
* );
56 DECLARE_LIST( FileStatList
, FileStat
* );
58 static char sCaseMap
[256];
59 static BOOL bCaseMap
= FALSE
;
60 static BOOL bDriveMap
= FALSE
;
69 void CreateCaseMapImpl();
70 void CreateDriveMapImpl();
72 static DriveMapItem aDriveMap
[26];
74 static BOOL bLastCaseSensitive
= FALSE
;
76 //====================================================================
78 int ApiRet2ToSolarError_Impl( int nApiRet
)
82 case NO_ERROR
: return ERRCODE_NONE
;
83 case ERROR_FILE_NOT_FOUND
: return ERRCODE_IO_NOTEXISTS
;
84 case ERROR_PATH_NOT_FOUND
: return ERRCODE_IO_NOTEXISTSPATH
;
85 case ERROR_TOO_MANY_OPEN_FILES
: return ERRCODE_IO_TOOMANYOPENFILES
;
86 case ERROR_ACCESS_DENIED
: return ERRCODE_IO_ACCESSDENIED
;
87 case ERROR_NOT_ENOUGH_MEMORY
: return ERRCODE_IO_OUTOFMEMORY
;
88 case ERROR_BAD_FORMAT
: return ERRCODE_IO_WRONGFORMAT
;
89 case ERROR_NOT_SAME_DEVICE
: return ERRCODE_IO_INVALIDDEVICE
;
90 case ERROR_WRITE_PROTECT
: return ERRCODE_IO_INVALIDDEVICE
;
91 case ERROR_BAD_UNIT
: return ERRCODE_IO_INVALIDDEVICE
;
92 case ERROR_CRC
: return ERRCODE_IO_INVALIDDEVICE
;
93 case ERROR_NOT_DOS_DISK
: return ERRCODE_IO_INVALIDDEVICE
;
94 case ERROR_WRITE_FAULT
: return ERRCODE_IO_CANTWRITE
;
95 case ERROR_READ_FAULT
: return ERRCODE_IO_CANTREAD
;
96 case ERROR_SHARING_VIOLATION
: return ERRCODE_IO_LOCKVIOLATION
;
97 case ERROR_LOCK_VIOLATION
: return ERRCODE_IO_LOCKVIOLATION
;
98 case ERROR_WRONG_DISK
: return ERRCODE_IO_LOCKVIOLATION
;
99 case ERROR_HANDLE_DISK_FULL
: return ERRCODE_IO_OUTOFSPACE
;
100 case ERROR_NOT_SUPPORTED
: return ERRCODE_IO_NOTSUPPORTED
;
101 case ERROR_DUP_NAME
: return ERRCODE_IO_ALREADYEXISTS
;
102 case ERROR_BAD_NETPATH
: return ERRCODE_IO_NOTEXISTSPATH
;
103 case ERROR_DEV_NOT_EXIST
: return ERRCODE_IO_NOTEXISTS
;
104 case ERROR_NETWORK_ACCESS_DENIED
: return ERRCODE_IO_ACCESSDENIED
;
105 case ERROR_INVALID_PARAMETER
: return ERRCODE_IO_INVALIDPARAMETER
;
106 case ERROR_NET_WRITE_FAULT
: return ERRCODE_IO_CANTWRITE
;
107 case ERROR_DEVICE_IN_USE
: return ERRCODE_IO_INVALIDPARAMETER
;
108 case ERROR_DISK_FULL
: return ERRCODE_IO_OUTOFSPACE
;
109 case ERROR_BAD_ARGUMENTS
: return ERRCODE_IO_INVALIDPARAMETER
;
110 case ERROR_BAD_PATHNAME
: return ERRCODE_IO_NOTEXISTSPATH
;
111 case ERROR_LOCK_FAILED
: return ERRCODE_IO_LOCKVIOLATION
;
112 case ERROR_LOCKED
: return ERRCODE_IO_LOCKVIOLATION
;
113 case ERROR_DUPLICATE_NAME
: return ERRCODE_IO_ALREADYEXISTS
;
114 case ERROR_DIRECTORY_IN_CDS
: return ERRCODE_IO_LOCKVIOLATION
;
115 case ERROR_CURRENT_DIRECTORY
: return ERRCODE_IO_LOCKVIOLATION
;
116 case ERROR_FILENAME_EXCED_RANGE
: return ERRCODE_IO_NAMETOOLONG
;
119 DBG_TRACE1( "FSys: unknown apiret error %d occured", nApiRet
);
120 return FSYS_ERR_UNKNOWN
;
123 //--------------------------------------------------------------------
125 char* volumeid( const char* pPfad
)
127 static FSINFO aFSInfoBuf
;
128 ULONG ulFSInfoLevel
= FSIL_VOLSER
;
131 nDriveNumber
= toupper(*pPfad
) - 'A' + 1;
133 if ( nDriveNumber
>= 3 )
135 APIRET rc
= DosQueryFSInfo(
136 nDriveNumber
, ulFSInfoLevel
, &aFSInfoBuf
, sizeof(FSINFO
) );
139 return (char*) aFSInfoBuf
.vol
.szVolLabel
;
144 //--------------------------------------------------------------------
146 /*************************************************************************
150 |* Beschreibung FSYS.SDW
151 |* Ersterstellung MI 26.04.91
152 |* Letzte Aenderung MA 02.12.91 13:30
154 *************************************************************************/
156 BOOL
DirEntry::ToAbs()
158 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
160 if ( FSYS_FLAG_VOLUME
== eFlag
)
162 eFlag
= FSYS_FLAG_ABSROOT
;
169 char sBuf
[_MAX_PATH
+ 1];
170 *this = DirEntry( String( getcwd( sBuf
, _MAX_PATH
), osl_getThreadTextEncoding() ) ) + *this;
175 /*************************************************************************
177 |* DirEntry::GetVolume()
179 |* Beschreibung FSYS.SDW
180 |* Ersterstellung MI 04.03.92
181 |* Letzte Aenderung MI 04.03.92
183 *************************************************************************/
185 String
DirEntry::GetVolume() const
187 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
190 const DirEntry
*pTop
= ImpGetTopPtr();
191 ByteString aName
= ByteString( pTop
->aName
).ToLowerAscii();
193 if ( ( pTop
->eFlag
== FSYS_FLAG_ABSROOT
||
194 pTop
->eFlag
== FSYS_FLAG_RELROOT
||
195 pTop
->eFlag
== FSYS_FLAG_VOLUME
)
196 && aName
!= "a:" && aName
!= "b:" && Exists() )
199 pVol
= volumeid( (char*) pTop
->aName
.GetBuffer() );
201 aRet
= String( pVol
, osl_getThreadTextEncoding());
207 /*************************************************************************
209 |* DirEntry::SetCWD()
211 |* Beschreibung FSYS.SDW
212 |* Ersterstellung MI 26.04.91
213 |* Letzte Aenderung MI 21.05.92
215 *************************************************************************/
217 BOOL
DirEntry::SetCWD( BOOL bSloppy
) const
219 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
221 if ( eFlag
== FSYS_FLAG_CURRENT
&& !aName
.Len() )
224 if ( !chdir(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
226 //nError = FSYS_ERR_OK;
230 if ( bSloppy
&& pParent
&&
231 !chdir(ByteString(pParent
->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
233 //nError = FSYS_ERR_OK;
237 //nError = FSYS_ERR_NOTADIRECTORY;
241 /*************************************************************************
243 |* DirEntry::MoveTo()
245 |* Beschreibung FSYS.SDW
246 |* Ersterstellung MI 26.04.91
247 |* Letzte Aenderung MA 02.12.91 14:07
249 *************************************************************************/
251 #if 0 // YD see dirent.cxx
252 BOOL
createLongNameEA( const PCSZ pszPath
, ULONG ulAttributes
, const String
& aLongName
);
254 FSysError
DirEntry::MoveTo( const DirEntry
& rDest
) const
256 DBG_CHKTHIS( DirEntry
, ImpCheckDirEntry
);
258 DirEntry
aTmpDest(rDest
);
259 FileStat
aTmpStat(aTmpDest
);
260 if ( aTmpStat
.IsKind(FSYS_KIND_DIR
) )
261 aTmpDest
+= DirEntry( GetName() );
263 String
aSource( GetFull() );
264 String
aDest( aTmpDest
.GetFull() );
265 String
aShortSource("");
266 String
aShortDest("");
268 if (Folder::IsAvailable())
270 if (IsLongNameOnFAT())
272 // in kurzen Pfad wandeln
273 ItemIDPath
aItemIDPath(aSource
);
274 aShortSource
= aItemIDPath
.GetHostNotationPath();
276 if (rDest
.IsLongNameOnFAT())
278 // in kurzen Pfad wandeln
279 ItemIDPath
aItemIDPath(aDest
);
280 aShortDest
= aItemIDPath
.GetHostNotationPath();
284 APIRET nRet
= DosMove( aShortSource
.Len()>0?(PSZ
)aShortSource
.GetStr():(PSZ
)aSource
.GetStr(),
285 aShortDest
.Len()>0?(PSZ
)aShortDest
.GetStr():(PSZ
)aDest
.GetStr());
287 if ( nRet
== ERROR_DIRECTORY_IN_CDS
||
288 nRet
== ERROR_CURRENT_DIRECTORY
)
290 // 2nd chance with modified CWD
291 DosSetCurrentDir( (PSZ
) "\\" );
292 nRet
= DosMove( aShortSource
.Len()>0?(PSZ
)aShortSource
.GetStr():(PSZ
)aSource
.GetStr(),
293 aShortDest
.Len()>0?(PSZ
)aShortDest
.GetStr():(PSZ
)aDest
.GetStr());
295 else if ( nRet
== ERROR_NOT_SAME_DEVICE
)
297 // other volume => copy+delete
298 FileCopier
aMover( *this, rDest
);
299 nRet
= aMover
.Execute( FSYS_ACTION_MOVE
|FSYS_ACTION_RECURSIVE
);
303 if ( (nRet
==NO_ERROR
) && aShortDest
.Len()>0)
305 createLongNameEA((const char*)aShortDest
, FILE_NORMAL
, rDest
.GetName());
308 return ApiRet2ToSolarError_Impl( nRet
);
312 //-------------------------------------------------------------------------
314 USHORT
DirReader_Impl::Init()
316 // Block-Devices auflisten?
317 if ( pDir
->eAttrMask
& FSYS_KIND_BLOCK
)
319 CreateDriveMapImpl();
321 DirEntry aCurrentDir
;
324 // einzeln auf Existenz und Masken-konformit"at pr"ufen
326 char sDrive
[3] = { '?', ':', 0 };
327 char sRoot
[4] = { '?', ':', '\\', 0 };
328 for ( char c
= 'a'; c
<= 'z'; c
++ )
332 DirEntry
* pDrive
= new DirEntry( sDrive
, FSYS_FLAG_VOLUME
, FSYS_STYLE_HOST
);
333 if ( pDir
->aNameMask
.Matches( String( ByteString(sDrive
), osl_getThreadTextEncoding()))
334 && aDriveMap
[c
-'a'].nKind
!= FSYS_KIND_UNKNOWN
)
336 if ( pDir
->pStatLst
) //Status fuer Sort gewuenscht?
338 FileStat
*pNewStat
= new FileStat( *pDrive
);
339 pDir
->ImpSortedInsert( pDrive
, pNewStat
);
342 pDir
->ImpSortedInsert( pDrive
, NULL
);
350 aCurrentDir
.SetCWD();
357 //-------------------------------------------------------------------------
359 USHORT
DirReader_Impl::Read()
363 pDosDir
= opendir( (char*) ByteString(aPath
, osl_getThreadTextEncoding()).GetBuffer() );
372 // Directories und Files auflisten?
373 if ( ( pDir
->eAttrMask
& FSYS_KIND_DIR
|| pDir
->eAttrMask
& FSYS_KIND_FILE
) &&
374 ( ( pDosEntry
= readdir( pDosDir
) ) != NULL
) )
376 String
aD_Name(pDosEntry
->d_name
, osl_getThreadTextEncoding());
377 if ( pDir
->aNameMask
.Matches( aD_Name
) )
380 0 == strcmp( pDosEntry
->d_name
, "." ) ? FSYS_FLAG_CURRENT
381 : 0 == strcmp( pDosEntry
->d_name
, ".." ) ? FSYS_FLAG_PARENT
383 DirEntry
*pTemp
= new DirEntry( ByteString(pDosEntry
->d_name
), eFlag
, FSYS_STYLE_UNX
);
385 pTemp
->ImpChangeParent( new DirEntry( *pParent
), FALSE
);
386 FileStat
aStat( *pTemp
);
387 if ( ( ( ( pDir
->eAttrMask
& FSYS_KIND_DIR
) &&
388 ( aStat
.IsKind( FSYS_KIND_DIR
) ) ) ||
389 ( ( pDir
->eAttrMask
& FSYS_KIND_FILE
) &&
390 !( aStat
.IsKind( FSYS_KIND_DIR
) ) ) ) &&
391 !( pDir
->eAttrMask
& FSYS_KIND_VISIBLE
&&
392 pDosEntry
->d_name
[0] == '.' ) )
394 if ( pDir
->pStatLst
) //Status fuer Sort gewuenscht?
395 pDir
->ImpSortedInsert( pTemp
, new FileStat( aStat
) );
397 pDir
->ImpSortedInsert( pTemp
, NULL
);;
409 /*************************************************************************
411 |* FileStat::FileStat()
413 |* Beschreibung FSYS.SDW
414 |* Ersterstellung MA 05.11.91
415 |* Letzte Aenderung MA 07.11.91
417 *************************************************************************/
419 FileStat::FileStat( const void *pInfo
, // struct dirent
420 const void * ): // dummy
428 struct dirent
*pDirent
= (struct dirent
*) pInfo
;
430 nSize
= pDirent
->d_size
;
432 aDateCreated
= MsDos2Date( (FDATE
*) &pDirent
->d_date
);
433 aTimeCreated
= MsDos2Time( (FTIME
*) &pDirent
->d_time
);
434 aDateModified
= aDateModified
;
435 aTimeModified
= aTimeModified
;
436 aDateAccessed
= aDateModified
;
437 aTimeAccessed
= aTimeModified
;
439 nKindFlags
= FSYS_KIND_FILE
;
440 if ( pDirent
->d_type
& DOS_DIRECT
)
441 nKindFlags
= FSYS_KIND_DIR
;
444 /*************************************************************************
446 |* FileStat::Update()
448 |* Beschreibung FSYS.SDW
449 |* Ersterstellung MI 11.06.91
450 |* Letzte Aenderung MA 07.11.91
452 *************************************************************************/
454 struct _FSYS_FSQBUFFER
460 BOOL
FileStat::Update( const DirEntry
& rDirEntry
, BOOL bAccessRemovableDevice
)
463 FSysPathStyle eStyle
= FSYS_STYLE_UNKNOWN
;
466 aDateCreated
= Date(0);
467 aTimeCreated
= Time(0);
468 aDateModified
= Date(0);
469 aTimeModified
= Time(0);
470 aDateAccessed
= Date(0);
471 aTimeAccessed
= Time(0);
473 if ( !rDirEntry
.IsValid() )
475 nError
= FSYS_ERR_NOTEXISTS
;
479 // Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt
480 if ( !rDirEntry
.aName
.Len() && rDirEntry
.eFlag
== FSYS_FLAG_ABSROOT
)
482 nKindFlags
= FSYS_KIND_DIR
;
483 nError
= FSYS_ERR_OK
;
487 // Sonderbehandlung falls es sich um eine Wildcard handelt
488 ByteString
aTempName( rDirEntry
.GetName(), osl_getThreadTextEncoding() );
489 if ( strchr( aTempName
.GetBuffer(), '?' ) ||
490 strchr( aTempName
.GetBuffer(), '*' ) ||
491 strchr( aTempName
.GetBuffer(), ';' ) )
493 nKindFlags
= FSYS_KIND_WILD
;
494 nError
= FSYS_ERR_OK
;
498 // Sonderbehandlung falls es sich um eine Root handelt
499 if ( rDirEntry
.eFlag
== FSYS_FLAG_VOLUME
||
500 rDirEntry
.eFlag
== FSYS_FLAG_ABSROOT
)
502 if ( rDirEntry
.eFlag
== FSYS_FLAG_VOLUME
)
503 nKindFlags
= FSYS_KIND_DEV
;
505 nKindFlags
= FSYS_KIND_DIR
;
507 if ( rDirEntry
.aName
.Len() == 2 )
510 CreateDriveMapImpl();
512 ByteString rDirEntryUpperCase
= ByteString( rDirEntry
.aName
).ToUpperAscii();
513 DriveMapItem
&rItem
= aDriveMap
[rDirEntryUpperCase
.GetChar(0) - 'A'];
516 nError
= ERRCODE_IO_INVALIDDEVICE
;
517 nKindFlags
= FSYS_KIND_UNKNOWN
;
522 if ( rDirEntry
.eFlag
== FSYS_FLAG_VOLUME
)
523 nKindFlags
|= FSYS_KIND_BLOCK
| rItem
.nKind
;
524 eStyle
= rItem
.nStyle
;
528 nError
= FSYS_ERR_OK
;
532 // disable error-boxes for hard-errors
533 DosError(FERR_DISABLEHARDERR
);
535 // Statusinformation vom Betriebssystem holen
536 DirEntry
aTempDirEntry( rDirEntry
);
539 aTempDirEntry
.ToAbs();
540 ByteString
aFullName( aTempDirEntry
.GetFull(), osl_getThreadTextEncoding() );
543 if (Folder::IsAvailable() && aTempDirEntry
.IsLongNameOnFAT())
545 // in String mit kurzem Pfad wandeln
546 ItemIDPath
aItemIDPath(aTempDirEntry
.GetFull());
547 aFullName
= ByteString( aItemIDPath
.GetHostNotationPath(), osl_getThreadTextEncoding() );
551 p
= (char *) aFullName
.GetBuffer();
553 FILESTATUS3 filestat
;
554 memset( &filestat
, 0, sizeof( filestat
) );
555 if( DosQueryPathInfo( (PSZ
)p
, 1, &filestat
, sizeof( filestat
) ) )
557 nError
= FSYS_ERR_NOTEXISTS
;
558 nKindFlags
= FSYS_KIND_UNKNOWN
;
562 nError
= FSYS_ERR_OK
;
563 nSize
= filestat
.cbFile
;
565 nKindFlags
= FSYS_KIND_UNKNOWN
;
566 if( filestat
.attrFile
& FILE_DIRECTORY
)
567 nKindFlags
|= FSYS_KIND_DIR
;
568 if ( nKindFlags
== FSYS_KIND_UNKNOWN
)
569 nKindFlags
= nKindFlags
| FSYS_KIND_FILE
;
571 aDateModified
= Date( filestat
.fdateLastWrite
.day
,
572 filestat
.fdateLastWrite
.month
,
573 filestat
.fdateLastWrite
.year
+ 1980 );
575 aTimeModified
= Time( filestat
.ftimeLastWrite
.hours
,
576 filestat
.ftimeLastWrite
.minutes
,
577 filestat
.ftimeLastWrite
.twosecs
*2 );
579 if ( filestat
.fdateCreation
.day
)
581 aDateCreated
= Date( filestat
.fdateCreation
.day
,
582 filestat
.fdateCreation
.month
,
583 filestat
.fdateCreation
.year
+ 1980 );
585 aTimeCreated
= Time( filestat
.ftimeCreation
.hours
,
586 filestat
.ftimeCreation
.minutes
,
587 filestat
.ftimeCreation
.twosecs
*2 );
591 aDateCreated
= aDateModified
;
592 aTimeCreated
= aTimeModified
;
595 if ( filestat
.fdateLastAccess
.day
> 0 )
597 aDateAccessed
= Date( filestat
.fdateLastAccess
.day
,
598 filestat
.fdateLastAccess
.month
,
599 filestat
.fdateLastAccess
.year
+ 1980 );
601 aTimeAccessed
= Time( filestat
.ftimeLastAccess
.hours
,
602 filestat
.ftimeLastAccess
.minutes
,
603 filestat
.ftimeLastAccess
.twosecs
*2 );
607 aDateAccessed
= aDateModified
;
608 aTimeAccessed
= aTimeModified
;
614 BOOL
IsRedirectable_Impl( const ByteString
&rPath
)
616 if ( rPath
.Len() >= 3 && ':' == rPath
.GetBuffer()[1] )
618 ByteString aVolume
= rPath
.Copy( 0, 3 );
619 DriveMapItem
&rItem
= aDriveMap
[toupper(aVolume
.GetChar(0)) - 'A'];
620 return FSYS_KIND_FIXED
!= rItem
.nKind
;
626 BOOL
IsRedirectable_Impl( const String
&rPath
)
628 if ( rPath
.Len() >= 3 && ':' == rPath
.GetStr()[1] )
630 DriveMapItem
&rItem
= aDriveMap
[toupper(rPath
[0]) - 'A'];
631 return FSYS_KIND_FIXED
!= rItem
.nKind
;
638 /*************************************************************************
642 |* Beschreibung liefert den Namens des Directories fuer temporaere
644 |* Ersterstellung MI 16.03.94
645 |* Letzte Aenderung MI 16.03.94
647 *************************************************************************/
649 const char* TempDirImpl( char *pBuf
)
653 BOOL bAppendTemp
= FALSE
; // mu\s noch \\temp angeh"angt werden
655 // Erstmal sehen, ob TEMP oder TMP gesetzt sind
656 nRet
= DosScanEnv( (PSZ
)"TEMP", &pVar
);
658 nRet
= DosScanEnv( (PSZ
)"temp", &pVar
);
660 nRet
= DosScanEnv( (PSZ
)"TMP", &pVar
);
662 nRet
= DosScanEnv( (PSZ
)"tmp", &pVar
);
664 nRet
= DosScanEnv( (PSZ
)"TMPDIR", &pVar
);
666 // falls das geklappt hat, und ein Backslash dranhaengt,
667 // oder falls es bisher nicht geklappt hat,
668 // muessen wir nachher einen Backslash entfernen
669 BOOL bRemoveBS
= nRet
|| *(pVar
+strlen(pVar
)-1) == '\\';
671 // Keine temp-Variable gefunden, dann gehen wir mal auf die Suche
672 // nach dem System-Laufwerk
675 nRet
= DosScanEnv( (PSZ
)"USER_INI",&pVar
);
676 bAppendTemp
= (0 == nRet
);
680 nRet
= DosScanEnv( (PSZ
)"SYSTEM_INI", &pVar
);
681 bAppendTemp
= (0 == nRet
);
684 // Wenn das immer noch nicht reicht nehmen wir eben die Root von C:
686 pVar
= (PSZ
)"c:\\temp\\";
688 pVar
= (PCSZ
)"c:\\temp\\";
690 strcpy( pBuf
, (const char*)pVar
);
692 // jetzt haengt ggf. ein Backlash dran, den wir abschneiden,
693 // ggf. inklusive dahinter haengendem Dateinamen
696 char *pTail
= pBuf
+ strlen(pBuf
) - 1;
697 for ( char cLast
= *pTail
; cLast
!= '\\'; cLast
= *(--pTail
) )
702 strcat( pBuf
, "\\temp" );
703 DirEntry( pBuf
).MakeDir();
708 #define CURRENT_COUNTRY 0
709 #define NLS_CODEPAGE 850
711 /*====================================================================
712 * CreateCaseMapImpl()
713 * creates a map of each character to convert to lower
714 *--------------------------------------------------------------------*/
717 void CreateCaseMapImpl()
719 // build a string starting with code 0 as first character upto 255
723 for ( n
= 0; n
< 256; ++n
)
726 // convert string to upper case
727 COUNTRYCODE aCountry
;
728 aCountry
.country
= CURRENT_COUNTRY
; /* Country code */
729 aCountry
.codepage
= NLS_CODEPAGE
; /* Code page */
730 DosMapCase( 255, &aCountry
, sTemp
+1 );
732 // fill a global buffer starting with code 0 as first character upto 255
733 for ( n
= 0; n
< 256; ++n
)
734 sCaseMap
[n
] = (char) n
;
736 // reorder by upper-code and store in a global buffer
737 for ( n
= 255; n
> 0; --n
)
738 // was this character converted?
739 if ( sTemp
[n
] != (char) n
)
740 // we found a convertion from upper to lower
741 sCaseMap
[ (unsigned char) sTemp
[n
] ] = (char) n
;
746 String
ToLowerImpl( const String
& rSource
)
751 // TH sagt: International ist zu langsam, also mit einer eigenen Map
752 ByteString
aLower( rSource
);
753 for ( USHORT n
= 0; n
< aLower
.Len(); ++n
)
754 aLower
[n
] = sCaseMap
[ (unsigned char) aLower
[n
] ];
759 /*====================================================================
760 * CreateDriveMapImpl()
761 * creates a map of drive-infos like FileSystem (style) and Kind (remote)
762 *--------------------------------------------------------------------*/
763 typedef struct _FSQBUFFER_
769 void CreateDriveMapImpl()
772 // !!!!! Hack, da der untere Teil mit Beta 2 noch abstuertzt !!!!!
774 for ( USHORT nDrive
= 0; nDrive
< 26; ++nDrive
)
776 if ( nDrive
< nFloppies
)
778 aDriveMap
[nDrive
].nKind
= FSYS_KIND_REMOVEABLE
;
779 aDriveMap
[nDrive
].nStyle
= FSYS_STYLE_FAT
;
783 aDriveMap
[nDrive
].nKind
= FSYS_KIND_UNKNOWN
;
784 aDriveMap
[nDrive
].nStyle
= FSYS_STYLE_UNKNOWN
;
788 aDriveMap
[2].nKind
= FSYS_KIND_FIXED
;
789 aDriveMap
[2].nStyle
= FSYS_STYLE_FAT
;
796 // disable error-boxes for hard-errors
797 DosError(FERR_DISABLEHARDERR
);
799 // determine number of floppy-drives
801 nRet
= DosDevConfig( (void*) &nFloppies
, DEVINFO_FLOPPY
);
804 for ( nDrive
= 0; nDrive
< 26; ++nDrive
)
806 if ( nDrive
< nFloppies
)
808 aDriveMap
[nDrive
].nKind
= FSYS_KIND_REMOVEABLE
;
809 aDriveMap
[nDrive
].nStyle
= FSYS_STYLE_FAT
;
813 aDriveMap
[nDrive
].nKind
= FSYS_KIND_UNKNOWN
;
814 aDriveMap
[nDrive
].nStyle
= FSYS_STYLE_UNKNOWN
;
818 // determine file-system via DosOpen/DocDevIOCtrl
819 for ( nDrive
= 2; nDrive
< 26; ++nDrive
)
824 char pDriveName
[3] = "#:";
825 pDriveName
[0] = nDrive
+'a';
827 nRet
= DosOpen( (PSZ
) pDriveName
, &nDevHandle
,
828 &nAction
, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS
,
829 OPEN_FLAGS_DASD
|OPEN_SHARE_DENYNONE
|OPEN_ACCESS_READONLY
,
836 BYTE nDriveId
= nDrive
;
837 ULONG nParaOutLen
, nDataOutLen
;
838 nRet
= DosDevIOCtl(nDevHandle
, 8, 0x20,
839 &nDriveId
, sizeof(nDriveId
), &nParaOutLen
,
840 &bFixed
, sizeof(bFixed
), &nDataOutLen
);
842 // prepare the drive-map
843 if ( !nRet
&& !bFixed
)
844 aDriveMap
[nDrive
].nKind
= FSYS_KIND_REMOVEABLE
;
847 DosClose(nDevHandle
);
849 else if ( nRet
== ERROR_NOT_READY
)
850 aDriveMap
[nDrive
].nKind
= FSYS_KIND_REMOVEABLE
| FSYS_KIND_CDROM
;
853 // determine file-system via FSAttach
855 for ( USHORT n
= 3; nRet
!= ERROR_NO_MORE_ITEMS
; ++n
)
857 nBufLen
= sizeof( aBuf
);
858 nRet
= DosQueryFSAttach( 0, n
, FSAIL_DRVNUMBER
,
859 (_FSQBUFFER2
*) &aBuf
, &nBufLen
);
862 nDrive
= toupper(aBuf
.aBuf
.szName
[0]) - 'A';
864 if ( aDriveMap
[nDrive
].nKind
== FSYS_KIND_UNKNOWN
)
865 aDriveMap
[nDrive
].nKind
=
866 aBuf
.aBuf
.iType
== 3 ? FSYS_KIND_FIXED
:
867 aBuf
.aBuf
.iType
== 4 ? FSYS_KIND_REMOTE
:
870 char *pType
= (char*)(aBuf
.aBuf
.szName
+ aBuf
.aBuf
.cbName
+ 1);
871 aDriveMap
[nDrive
].nStyle
=
872 strcmp( pType
, "FAT" ) == 0 ? FSYS_STYLE_FAT
:
873 strcmp( pType
, "FAT32" ) == 0 ? FSYS_STYLE_VFAT
:
874 strcmp( pType
, "NTFS" ) == 0 ? FSYS_STYLE_NTFS
:
875 strcmp( pType
, "HPFS" ) == 0 ? FSYS_STYLE_HPFS
:
876 strcmp( pType
, "JFS" ) == 0 ? FSYS_STYLE_HPFS
:
877 strcmp( pType
, "RAMFS" ) == 0 ? FSYS_STYLE_HPFS
:
878 strcmp( pType
, "NDFS32" ) == 0 ? FSYS_STYLE_HPFS
:
879 strcmp( pType
, "NWFS" ) == 0 ? FSYS_STYLE_NWFS
:
880 strcmp( pType
, "EXT2" ) == 0 ? FSYS_STYLE_UNX
:
881 strcmp( pType
, "NFS" ) == 0 ? FSYS_STYLE_UNX
:
883 if ( strcmp( pType
, "CDFS" ) == 0 )
884 aDriveMap
[nDrive
].nKind
= FSYS_KIND_CDROM
|FSYS_KIND_REMOVEABLE
;
892 Time
MsDos2Time( const time_t *pTimeT
)
894 tm
*pTm
= localtime( pTimeT
);
896 return Time( pTm
->tm_hour
, pTm
->tm_min
, pTm
->tm_sec
);
901 Date
MsDos2Date( const time_t *pTimeT
)
903 tm
*pTm
= localtime( pTimeT
);
905 return Date( pTm
->tm_mday
, pTm
->tm_mon
+ 1, pTm
->tm_year
);
910 /*************************************************************************
912 |* DirEntry::GetPathStyle() const
915 |* Ersterstellung MI 11.05.95
916 |* Letzte Aenderung MI 11.05.95
918 *************************************************************************/
920 FSysPathStyle
DirEntry::GetPathStyle( const String
&rDevice
)
922 ByteString
aRootDir(rDevice
, osl_getThreadTextEncoding());
924 if ( aRootDir
.Len()==0 || ( aRootDir
.Len() > 1 && aRootDir
.GetChar(1) != ':' ) )
925 return FSYS_STYLE_UNKNOWN
;
928 CreateDriveMapImpl();
929 return aDriveMap
[toupper(aRootDir
.GetChar(0)) - 'A'].nStyle
;
932 /*************************************************************************
934 |* DirEntry::IsCaseSensitive() const
937 |* Ersterstellung TPF 26.02.1999
940 *************************************************************************/
942 BOOL
DirEntry::IsCaseSensitive( FSysPathStyle eFormatter
) const
944 if (eFormatter
==FSYS_STYLE_HOST
)
946 if (GetPathStyle(GetDevice().GetName()) == FSYS_STYLE_UNX
)
957 BOOL isCaseSensitive
= FALSE
; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv
958 switch ( eFormatter
)
962 case FSYS_STYLE_VFAT
:
963 case FSYS_STYLE_NTFS
:
964 case FSYS_STYLE_NWFS
:
965 case FSYS_STYLE_HPFS
:
966 case FSYS_STYLE_DETECT
:
968 isCaseSensitive
= FALSE
;
971 case FSYS_STYLE_SYSV
:
974 isCaseSensitive
= TRUE
;
979 isCaseSensitive
= FALSE
; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv
983 return isCaseSensitive
;
990 //=========================================================================
992 ErrCode
FileStat::QueryDiskSpace( const String
&rPath
,
993 BigInt
&rFreeBytes
, BigInt
&rTotalBytes
)
995 FSALLOCATE aFSInfoBuf
;
996 ByteString
aVol( DirEntry(rPath
).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding());
997 ULONG nDriveNumber
= toupper( aVol
.GetChar(0) ) - 'A' + 1;
999 APIRET rc
= DosQueryFSInfo( nDriveNumber
, FSIL_ALLOC
,
1000 &aFSInfoBuf
, sizeof(aFSInfoBuf
) );
1002 return Sys2SolarError_Impl( rc
);
1004 BigInt
aBytesPerCluster( BigInt(aFSInfoBuf
.cbSector
) *
1005 BigInt(aFSInfoBuf
.cSectorUnit
) );
1006 rFreeBytes
= aBytesPerCluster
* BigInt(aFSInfoBuf
.cUnitAvail
);
1007 rTotalBytes
= aBytesPerCluster
* BigInt(aFSInfoBuf
.cUnit
);
1011 //=========================================================================
1013 void FSysEnableSysErrorBox( BOOL bEnable
)
1015 DosError( bEnable
? 0 : FERR_DISABLEHARDERR
);