Update ooo320-m1
[ooovba.git] / tools / source / fsys / os2.cxx
blob8891d566f0fd881136ce589a271d563947001849
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: os2.cxx,v $
10 * $Revision: 1.8 $
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
33 #include <stdlib.h>
35 #ifdef __BORLANDC__
36 #include <alloc.h>
37 #else
38 #include <malloc.h>
39 #endif
40 #include <tools/debug.hxx>
41 #include <tools/list.hxx>
42 #include <tools/bigint.hxx>
43 #include <tools/fsys.hxx>
44 #include "comdep.hxx"
46 #ifdef OS2
47 #ifndef _VOS_MUTEX_HXX //autogen
48 #include <vos/mutex.hxx>
49 #endif
50 #endif
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;
62 struct DriveMapItem
64 DirEntryKind nKind;
65 char cName;
66 FSysPathStyle nStyle;
69 void CreateCaseMapImpl();
70 void CreateDriveMapImpl();
72 static DriveMapItem aDriveMap[26];
74 static BOOL bLastCaseSensitive = FALSE;
76 //====================================================================
78 int ApiRet2ToSolarError_Impl( int nApiRet )
80 switch ( 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;
129 ULONG nDriveNumber;
131 nDriveNumber = toupper(*pPfad) - 'A' + 1;
133 if ( nDriveNumber >= 3 )
135 APIRET rc = DosQueryFSInfo(
136 nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) );
137 if ( rc )
138 return 0;
139 return (char*) aFSInfoBuf.vol.szVolLabel;
141 return 0;
144 //--------------------------------------------------------------------
146 /*************************************************************************
148 |* DirEntry::ToAbs()
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;
163 return TRUE;
166 if ( IsAbs() )
167 return TRUE;
169 char sBuf[_MAX_PATH + 1];
170 *this = DirEntry( String( getcwd( sBuf, _MAX_PATH ), osl_getThreadTextEncoding() ) ) + *this;
172 return IsAbs();
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 );
189 String aRet;
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() )
198 const char *pVol;
199 pVol = volumeid( (char*) pTop->aName.GetBuffer() );
200 if (pVol)
201 aRet = String( pVol, osl_getThreadTextEncoding());
204 return aRet;
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() )
222 return TRUE;
224 if ( !chdir(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
226 //nError = FSYS_ERR_OK;
227 return TRUE;
230 if ( bSloppy && pParent &&
231 !chdir(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
233 //nError = FSYS_ERR_OK;
234 return TRUE;
237 //nError = FSYS_ERR_NOTADIRECTORY;
238 return FALSE;
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 );
300 return nRet;
303 if ( (nRet==NO_ERROR) && aShortDest.Len()>0)
305 createLongNameEA((const char*)aShortDest, FILE_NORMAL, rDest.GetName());
308 return ApiRet2ToSolarError_Impl( nRet );
310 #endif // 0
312 //-------------------------------------------------------------------------
314 USHORT DirReader_Impl::Init()
316 // Block-Devices auflisten?
317 if ( pDir->eAttrMask & FSYS_KIND_BLOCK )
319 CreateDriveMapImpl();
320 // CWD merken
321 DirEntry aCurrentDir;
322 aCurrentDir.ToAbs();
324 // einzeln auf Existenz und Masken-konformit"at pr"ufen
325 USHORT nRead = 0;
326 char sDrive[3] = { '?', ':', 0 };
327 char sRoot[4] = { '?', ':', '\\', 0 };
328 for ( char c = 'a'; c <= 'z'; c++ )
330 sDrive[0] = c;
331 sRoot[0] = 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 );
341 else
342 pDir->ImpSortedInsert( pDrive, NULL );
343 ++nRead;
345 else
346 delete pDrive;
349 // CWD restaurieren
350 aCurrentDir.SetCWD();
351 return nRead;
354 return 0;
357 //-------------------------------------------------------------------------
359 USHORT DirReader_Impl::Read()
361 if (!pDosDir)
363 pDosDir = opendir( (char*) ByteString(aPath, osl_getThreadTextEncoding()).GetBuffer() );
366 if (!pDosDir)
368 bReady = TRUE;
369 return 0;
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 ) )
379 DirEntryFlag eFlag =
380 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT
381 : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT
382 : FSYS_FLAG_NORMAL;
383 DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name), eFlag, FSYS_STYLE_UNX );
384 if ( pParent )
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 ) );
396 else
397 pDir->ImpSortedInsert( pTemp, NULL );;
398 return 1;
400 else
401 delete pTemp;
404 else
405 bReady = TRUE;
406 return 0;
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
421 aDateCreated(0),
422 aTimeCreated(0),
423 aDateModified(0),
424 aTimeModified(0),
425 aDateAccessed(0),
426 aTimeAccessed(0)
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
456 FSQBUFFER2 aBuf;
457 UCHAR sBuf[256];
460 BOOL FileStat::Update( const DirEntry& rDirEntry, BOOL bAccessRemovableDevice )
462 nSize = 0;
463 FSysPathStyle eStyle = FSYS_STYLE_UNKNOWN;
464 aCreator.Erase();
465 aType.Erase();
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;
476 return FALSE;
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;
484 return TRUE;
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;
495 return TRUE;
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;
504 else
505 nKindFlags = FSYS_KIND_DIR;
507 if ( rDirEntry.aName.Len() == 2 )
509 if ( !bDriveMap )
510 CreateDriveMapImpl();
512 ByteString rDirEntryUpperCase = ByteString( rDirEntry.aName ).ToUpperAscii();
513 DriveMapItem &rItem = aDriveMap[rDirEntryUpperCase.GetChar(0) - 'A'];
514 if ( !rItem.nKind )
516 nError = ERRCODE_IO_INVALIDDEVICE;
517 nKindFlags = FSYS_KIND_UNKNOWN;
518 return FALSE;
520 else
522 if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME )
523 nKindFlags |= FSYS_KIND_BLOCK | rItem.nKind;
524 eStyle = rItem.nStyle;
528 nError = FSYS_ERR_OK;
529 return TRUE;
532 // disable error-boxes for hard-errors
533 DosError(FERR_DISABLEHARDERR);
535 // Statusinformation vom Betriebssystem holen
536 DirEntry aTempDirEntry( rDirEntry );
537 char* p;
539 aTempDirEntry.ToAbs();
540 ByteString aFullName( aTempDirEntry.GetFull(), osl_getThreadTextEncoding() );
542 #if 0 // YD
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() );
549 #endif
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;
559 return FALSE;
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 );
589 else
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 );
605 else
607 aDateAccessed = aDateModified;
608 aTimeAccessed = aTimeModified;
611 return TRUE;
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;
622 return FALSE;
625 #if 0
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;
633 return FALSE;
635 #endif
638 /*************************************************************************
640 |* TempDirImpl()
642 |* Beschreibung liefert den Namens des Directories fuer temporaere
643 |* Dateien
644 |* Ersterstellung MI 16.03.94
645 |* Letzte Aenderung MI 16.03.94
647 *************************************************************************/
649 const char* TempDirImpl( char *pBuf )
651 PSZ pVar;
652 USHORT nRet;
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 );
657 if( nRet )
658 nRet = DosScanEnv( (PSZ)"temp", &pVar );
659 if( nRet )
660 nRet = DosScanEnv( (PSZ)"TMP", &pVar );
661 if( nRet )
662 nRet = DosScanEnv( (PSZ)"tmp", &pVar );
663 if( nRet )
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
673 if( nRet )
675 nRet = DosScanEnv( (PSZ)"USER_INI",&pVar );
676 bAppendTemp = (0 == nRet);
678 if( nRet )
680 nRet = DosScanEnv( (PSZ)"SYSTEM_INI", &pVar );
681 bAppendTemp = (0 == nRet);
683 if( nRet )
684 // Wenn das immer noch nicht reicht nehmen wir eben die Root von C:
685 #ifdef __BORLANDC__
686 pVar = (PSZ)"c:\\temp\\";
687 #else
688 pVar = (PCSZ)"c:\\temp\\";
689 #endif
690 strcpy( pBuf, (const char*)pVar );
692 // jetzt haengt ggf. ein Backlash dran, den wir abschneiden,
693 // ggf. inklusive dahinter haengendem Dateinamen
694 if ( bRemoveBS )
696 char *pTail = pBuf + strlen(pBuf) - 1;
697 for ( char cLast = *pTail; cLast != '\\'; cLast = *(--pTail) )
698 *pTail = 0;
701 if ( bAppendTemp )
702 strcat( pBuf, "\\temp" );
703 DirEntry( pBuf ).MakeDir();
705 return pBuf;
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 *--------------------------------------------------------------------*/
716 #if 0
717 void CreateCaseMapImpl()
719 // build a string starting with code 0 as first character upto 255
720 char sTemp[256];
721 USHORT n;
723 for ( n = 0; n < 256; ++n )
724 sTemp[n] = (char) 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;
743 bCaseMap = TRUE;
746 String ToLowerImpl( const String& rSource )
748 if ( !bCaseMap )
749 CreateCaseMapImpl();
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] ];
755 return aLower;
757 #endif // 0
759 /*====================================================================
760 * CreateDriveMapImpl()
761 * creates a map of drive-infos like FileSystem (style) and Kind (remote)
762 *--------------------------------------------------------------------*/
763 typedef struct _FSQBUFFER_
765 FSQBUFFER2 aBuf;
766 UCHAR sBuf[64];
767 } FSQBUFFER_;
769 void CreateDriveMapImpl()
771 #ifdef POWERPC
772 // !!!!! Hack, da der untere Teil mit Beta 2 noch abstuertzt !!!!!
773 BYTE nFloppies = 1;
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;
781 else
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;
790 #else
791 FSQBUFFER_ aBuf;
792 ULONG nBufLen;
793 APIRET nRet;
794 USHORT nDrive;
796 // disable error-boxes for hard-errors
797 DosError(FERR_DISABLEHARDERR);
799 // determine number of floppy-drives
800 BYTE nFloppies;
801 nRet = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
803 // reset the map
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;
811 else
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 )
821 // open drive
822 BOOL bFixed;
823 HFILE nDevHandle;
824 char pDriveName[3] = "#:";
825 pDriveName[0] = nDrive+'a';
826 ULONG nAction;
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,
830 0 );
832 // exists?
833 if ( !nRet )
835 // removeable?
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;
846 // close drive
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
854 nRet = 0;
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 );
860 if ( !nRet )
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 :
868 FSYS_KIND_UNKNOWN;
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 :
882 FSYS_STYLE_UNKNOWN;
883 if ( strcmp( pType, "CDFS" ) == 0 )
884 aDriveMap[nDrive].nKind = FSYS_KIND_CDROM|FSYS_KIND_REMOVEABLE;
887 #endif
889 bDriveMap = TRUE;
892 Time MsDos2Time( const time_t *pTimeT )
894 tm *pTm = localtime( pTimeT );
895 if ( pTm )
896 return Time( pTm->tm_hour, pTm->tm_min, pTm->tm_sec );
897 else
898 return Time(0);
901 Date MsDos2Date( const time_t *pTimeT )
903 tm *pTm = localtime( pTimeT );
904 if ( pTm )
905 return Date( pTm->tm_mday, pTm->tm_mon + 1, pTm->tm_year );
906 else
907 return Date(0);
910 /*************************************************************************
912 |* DirEntry::GetPathStyle() const
914 |* Beschreibung
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());
923 // UNC-Pathname?
924 if ( aRootDir.Len()==0 || ( aRootDir.Len() > 1 && aRootDir.GetChar(1) != ':' ) )
925 return FSYS_STYLE_UNKNOWN;
927 if ( !bDriveMap )
928 CreateDriveMapImpl();
929 return aDriveMap[toupper(aRootDir.GetChar(0)) - 'A'].nStyle;
932 /*************************************************************************
934 |* DirEntry::IsCaseSensitive() const
936 |* Beschreibung
937 |* Ersterstellung TPF 26.02.1999
938 |* Letzte Aenderung
940 *************************************************************************/
942 BOOL DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
944 if (eFormatter==FSYS_STYLE_HOST)
946 if (GetPathStyle(GetDevice().GetName()) == FSYS_STYLE_UNX)
948 return TRUE;
950 else
952 return FALSE;
955 else
957 BOOL isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv
958 switch ( eFormatter )
960 case FSYS_STYLE_MAC:
961 case FSYS_STYLE_FAT:
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;
969 break;
971 case FSYS_STYLE_SYSV:
972 case FSYS_STYLE_BSD:
974 isCaseSensitive = TRUE;
975 break;
977 default:
979 isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv
980 break;
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) );
1001 if ( rc )
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);
1008 return 0;
1011 //=========================================================================
1013 void FSysEnableSysErrorBox( BOOL bEnable )
1015 DosError( bEnable ? 0 : FERR_DISABLEHARDERR );