1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #define INCL_DOSEXCEPTIONS 29 30 #include <stdlib.h> 31 32 #ifdef __BORLANDC__ 33 #include <alloc.h> 34 #else 35 #include <malloc.h> 36 #endif 37 #include <tools/debug.hxx> 38 #include <tools/list.hxx> 39 #include <tools/bigint.hxx> 40 #include <tools/fsys.hxx> 41 #include "comdep.hxx" 42 43 #ifdef OS2 44 #ifndef _VOS_MUTEX_HXX //autogen 45 #include <vos/mutex.hxx> 46 #endif 47 #endif 48 49 int Sys2SolarError_Impl( int nSysErr ); 50 51 DECLARE_LIST( DirEntryList, DirEntry* ); 52 DECLARE_LIST( FSysSortList, FSysSort* ); 53 DECLARE_LIST( FileStatList, FileStat* ); 54 55 static char sCaseMap[256]; 56 static BOOL bCaseMap = FALSE; 57 static BOOL bDriveMap = FALSE; 58 59 struct DriveMapItem 60 { 61 DirEntryKind nKind; 62 char cName; 63 FSysPathStyle nStyle; 64 }; 65 66 void CreateCaseMapImpl(); 67 void CreateDriveMapImpl(); 68 69 static DriveMapItem aDriveMap[26]; 70 71 static BOOL bLastCaseSensitive = FALSE; 72 73 //==================================================================== 74 75 int ApiRet2ToSolarError_Impl( int nApiRet ) 76 { 77 switch ( nApiRet ) 78 { 79 case NO_ERROR: return ERRCODE_NONE; 80 case ERROR_FILE_NOT_FOUND: return ERRCODE_IO_NOTEXISTS; 81 case ERROR_PATH_NOT_FOUND: return ERRCODE_IO_NOTEXISTSPATH; 82 case ERROR_TOO_MANY_OPEN_FILES: return ERRCODE_IO_TOOMANYOPENFILES; 83 case ERROR_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED; 84 case ERROR_NOT_ENOUGH_MEMORY: return ERRCODE_IO_OUTOFMEMORY; 85 case ERROR_BAD_FORMAT: return ERRCODE_IO_WRONGFORMAT; 86 case ERROR_NOT_SAME_DEVICE: return ERRCODE_IO_INVALIDDEVICE; 87 case ERROR_WRITE_PROTECT: return ERRCODE_IO_INVALIDDEVICE; 88 case ERROR_BAD_UNIT: return ERRCODE_IO_INVALIDDEVICE; 89 case ERROR_CRC: return ERRCODE_IO_INVALIDDEVICE; 90 case ERROR_NOT_DOS_DISK: return ERRCODE_IO_INVALIDDEVICE; 91 case ERROR_WRITE_FAULT: return ERRCODE_IO_CANTWRITE; 92 case ERROR_READ_FAULT: return ERRCODE_IO_CANTREAD; 93 case ERROR_SHARING_VIOLATION: return ERRCODE_IO_LOCKVIOLATION; 94 case ERROR_LOCK_VIOLATION: return ERRCODE_IO_LOCKVIOLATION; 95 case ERROR_WRONG_DISK: return ERRCODE_IO_LOCKVIOLATION; 96 case ERROR_HANDLE_DISK_FULL: return ERRCODE_IO_OUTOFSPACE; 97 case ERROR_NOT_SUPPORTED: return ERRCODE_IO_NOTSUPPORTED; 98 case ERROR_DUP_NAME: return ERRCODE_IO_ALREADYEXISTS; 99 case ERROR_BAD_NETPATH: return ERRCODE_IO_NOTEXISTSPATH; 100 case ERROR_DEV_NOT_EXIST: return ERRCODE_IO_NOTEXISTS; 101 case ERROR_NETWORK_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED; 102 case ERROR_INVALID_PARAMETER: return ERRCODE_IO_INVALIDPARAMETER; 103 case ERROR_NET_WRITE_FAULT: return ERRCODE_IO_CANTWRITE; 104 case ERROR_DEVICE_IN_USE: return ERRCODE_IO_INVALIDPARAMETER; 105 case ERROR_DISK_FULL: return ERRCODE_IO_OUTOFSPACE; 106 case ERROR_BAD_ARGUMENTS: return ERRCODE_IO_INVALIDPARAMETER; 107 case ERROR_BAD_PATHNAME: return ERRCODE_IO_NOTEXISTSPATH; 108 case ERROR_LOCK_FAILED: return ERRCODE_IO_LOCKVIOLATION; 109 case ERROR_LOCKED: return ERRCODE_IO_LOCKVIOLATION; 110 case ERROR_DUPLICATE_NAME: return ERRCODE_IO_ALREADYEXISTS; 111 case ERROR_DIRECTORY_IN_CDS: return ERRCODE_IO_LOCKVIOLATION; 112 case ERROR_CURRENT_DIRECTORY: return ERRCODE_IO_LOCKVIOLATION; 113 case ERROR_FILENAME_EXCED_RANGE: return ERRCODE_IO_NAMETOOLONG; 114 } 115 116 DBG_TRACE1( "FSys: unknown apiret error %d occured", nApiRet ); 117 return FSYS_ERR_UNKNOWN; 118 } 119 120 //-------------------------------------------------------------------- 121 122 char* volumeid( const char* pPfad ) 123 { 124 static FSINFO aFSInfoBuf; 125 ULONG ulFSInfoLevel = FSIL_VOLSER; 126 ULONG nDriveNumber; 127 128 nDriveNumber = toupper(*pPfad) - 'A' + 1; 129 130 if ( nDriveNumber >= 3 ) 131 { 132 APIRET rc = DosQueryFSInfo( 133 nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) ); 134 if ( rc ) 135 return 0; 136 return (char*) aFSInfoBuf.vol.szVolLabel; 137 } 138 return 0; 139 } 140 141 //-------------------------------------------------------------------- 142 143 /************************************************************************* 144 |* 145 |* DirEntry::ToAbs() 146 |* 147 |* Beschreibung FSYS.SDW 148 |* Ersterstellung MI 26.04.91 149 |* Letzte Aenderung MA 02.12.91 13:30 150 |* 151 *************************************************************************/ 152 153 BOOL DirEntry::ToAbs() 154 { 155 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); 156 157 if ( FSYS_FLAG_VOLUME == eFlag ) 158 { 159 eFlag = FSYS_FLAG_ABSROOT; 160 return TRUE; 161 } 162 163 if ( IsAbs() ) 164 return TRUE; 165 166 char sBuf[_MAX_PATH + 1]; 167 *this = DirEntry( String( getcwd( sBuf, _MAX_PATH ), osl_getThreadTextEncoding() ) ) + *this; 168 169 return IsAbs(); 170 } 171 172 /************************************************************************* 173 |* 174 |* DirEntry::GetVolume() 175 |* 176 |* Beschreibung FSYS.SDW 177 |* Ersterstellung MI 04.03.92 178 |* Letzte Aenderung MI 04.03.92 179 |* 180 *************************************************************************/ 181 182 String DirEntry::GetVolume() const 183 { 184 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); 185 186 String aRet; 187 const DirEntry *pTop = ImpGetTopPtr(); 188 ByteString aName = ByteString( pTop->aName ).ToLowerAscii(); 189 190 if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT || 191 pTop->eFlag == FSYS_FLAG_RELROOT || 192 pTop->eFlag == FSYS_FLAG_VOLUME ) 193 && aName != "a:" && aName != "b:" && Exists() ) 194 { 195 const char *pVol; 196 pVol = volumeid( (char*) pTop->aName.GetBuffer() ); 197 if (pVol) 198 aRet = String( pVol, osl_getThreadTextEncoding()); 199 } 200 201 return aRet; 202 } 203 204 /************************************************************************* 205 |* 206 |* DirEntry::SetCWD() 207 |* 208 |* Beschreibung FSYS.SDW 209 |* Ersterstellung MI 26.04.91 210 |* Letzte Aenderung MI 21.05.92 211 |* 212 *************************************************************************/ 213 214 BOOL DirEntry::SetCWD( BOOL bSloppy ) const 215 { 216 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); 217 218 if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() ) 219 return TRUE; 220 221 if ( !chdir(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) ) 222 { 223 //nError = FSYS_ERR_OK; 224 return TRUE; 225 } 226 227 if ( bSloppy && pParent && 228 !chdir(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) ) 229 { 230 //nError = FSYS_ERR_OK; 231 return TRUE; 232 } 233 234 //nError = FSYS_ERR_NOTADIRECTORY; 235 return FALSE; 236 } 237 238 /************************************************************************* 239 |* 240 |* DirEntry::MoveTo() 241 |* 242 |* Beschreibung FSYS.SDW 243 |* Ersterstellung MI 26.04.91 244 |* Letzte Aenderung MA 02.12.91 14:07 245 |* 246 *************************************************************************/ 247 248 #if 0 // YD see dirent.cxx 249 BOOL createLongNameEA( const PCSZ pszPath, ULONG ulAttributes, const String& aLongName ); 250 251 FSysError DirEntry::MoveTo( const DirEntry& rDest ) const 252 { 253 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); 254 255 DirEntry aTmpDest(rDest); 256 FileStat aTmpStat(aTmpDest); 257 if ( aTmpStat.IsKind(FSYS_KIND_DIR) ) 258 aTmpDest += DirEntry( GetName() ); 259 260 String aSource( GetFull() ); 261 String aDest( aTmpDest.GetFull() ); 262 String aShortSource(""); 263 String aShortDest(""); 264 265 if (Folder::IsAvailable()) 266 { 267 if (IsLongNameOnFAT()) 268 { 269 // in kurzen Pfad wandeln 270 ItemIDPath aItemIDPath(aSource); 271 aShortSource = aItemIDPath.GetHostNotationPath(); 272 } 273 if (rDest.IsLongNameOnFAT()) 274 { 275 // in kurzen Pfad wandeln 276 ItemIDPath aItemIDPath(aDest); 277 aShortDest = aItemIDPath.GetHostNotationPath(); 278 } 279 } 280 281 APIRET nRet = DosMove( aShortSource.Len()>0?(PSZ)aShortSource.GetStr():(PSZ)aSource.GetStr(), 282 aShortDest.Len()>0?(PSZ)aShortDest.GetStr():(PSZ)aDest.GetStr()); 283 284 if ( nRet == ERROR_DIRECTORY_IN_CDS || 285 nRet == ERROR_CURRENT_DIRECTORY ) 286 { 287 // 2nd chance with modified CWD 288 DosSetCurrentDir( (PSZ) "\\" ); 289 nRet = DosMove( aShortSource.Len()>0?(PSZ)aShortSource.GetStr():(PSZ)aSource.GetStr(), 290 aShortDest.Len()>0?(PSZ)aShortDest.GetStr():(PSZ)aDest.GetStr()); 291 } 292 else if ( nRet == ERROR_NOT_SAME_DEVICE ) 293 { 294 // other volume => copy+delete 295 FileCopier aMover( *this, rDest ); 296 nRet = aMover.Execute( FSYS_ACTION_MOVE|FSYS_ACTION_RECURSIVE ); 297 return nRet; 298 } 299 300 if ( (nRet==NO_ERROR) && aShortDest.Len()>0) 301 { 302 createLongNameEA((const char*)aShortDest, FILE_NORMAL, rDest.GetName()); 303 } 304 305 return ApiRet2ToSolarError_Impl( nRet ); 306 } 307 #endif // 0 308 309 //------------------------------------------------------------------------- 310 311 USHORT DirReader_Impl::Init() 312 { 313 // Block-Devices auflisten? 314 if ( pDir->eAttrMask & FSYS_KIND_BLOCK ) 315 { 316 CreateDriveMapImpl(); 317 // CWD merken 318 DirEntry aCurrentDir; 319 aCurrentDir.ToAbs(); 320 321 // einzeln auf Existenz und Masken-konformit"at pr"ufen 322 USHORT nRead = 0; 323 char sDrive[3] = { '?', ':', 0 }; 324 char sRoot[4] = { '?', ':', '\\', 0 }; 325 for ( char c = 'a'; c <= 'z'; c++ ) 326 { 327 sDrive[0] = c; 328 sRoot[0] = c; 329 DirEntry* pDrive = new DirEntry( sDrive, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST ); 330 if ( pDir->aNameMask.Matches( String( ByteString(sDrive), osl_getThreadTextEncoding())) 331 && aDriveMap[c-'a'].nKind != FSYS_KIND_UNKNOWN ) 332 { 333 if ( pDir->pStatLst ) //Status fuer Sort gewuenscht? 334 { 335 FileStat *pNewStat = new FileStat( *pDrive ); 336 pDir->ImpSortedInsert( pDrive, pNewStat ); 337 } 338 else 339 pDir->ImpSortedInsert( pDrive, NULL ); 340 ++nRead; 341 } 342 else 343 delete pDrive; 344 } 345 346 // CWD restaurieren 347 aCurrentDir.SetCWD(); 348 return nRead; 349 } 350 351 return 0; 352 } 353 354 //------------------------------------------------------------------------- 355 356 USHORT DirReader_Impl::Read() 357 { 358 if (!pDosDir) 359 { 360 pDosDir = opendir( (char*) ByteString(aPath, osl_getThreadTextEncoding()).GetBuffer() ); 361 } 362 363 if (!pDosDir) 364 { 365 bReady = TRUE; 366 return 0; 367 } 368 369 // Directories und Files auflisten? 370 if ( ( pDir->eAttrMask & FSYS_KIND_DIR || pDir->eAttrMask & FSYS_KIND_FILE ) && 371 ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) ) 372 { 373 String aD_Name(pDosEntry->d_name, osl_getThreadTextEncoding()); 374 if ( pDir->aNameMask.Matches( aD_Name ) ) 375 { 376 DirEntryFlag eFlag = 377 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT 378 : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT 379 : FSYS_FLAG_NORMAL; 380 DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name), eFlag, FSYS_STYLE_UNX ); 381 if ( pParent ) 382 pTemp->ImpChangeParent( new DirEntry( *pParent ), FALSE); 383 FileStat aStat( *pTemp ); 384 if ( ( ( ( pDir->eAttrMask & FSYS_KIND_DIR ) && 385 ( aStat.IsKind( FSYS_KIND_DIR ) ) ) || 386 ( ( pDir->eAttrMask & FSYS_KIND_FILE ) && 387 !( aStat.IsKind( FSYS_KIND_DIR ) ) ) ) && 388 !( pDir->eAttrMask & FSYS_KIND_VISIBLE && 389 pDosEntry->d_name[0] == '.' ) ) 390 { 391 if ( pDir->pStatLst ) //Status fuer Sort gewuenscht? 392 pDir->ImpSortedInsert( pTemp, new FileStat( aStat ) ); 393 else 394 pDir->ImpSortedInsert( pTemp, NULL );; 395 return 1; 396 } 397 else 398 delete pTemp; 399 } 400 } 401 else 402 bReady = TRUE; 403 return 0; 404 } 405 406 /************************************************************************* 407 |* 408 |* FileStat::FileStat() 409 |* 410 |* Beschreibung FSYS.SDW 411 |* Ersterstellung MA 05.11.91 412 |* Letzte Aenderung MA 07.11.91 413 |* 414 *************************************************************************/ 415 416 FileStat::FileStat( const void *pInfo, // struct dirent 417 const void * ): // dummy 418 aDateCreated(0), 419 aTimeCreated(0), 420 aDateModified(0), 421 aTimeModified(0), 422 aDateAccessed(0), 423 aTimeAccessed(0) 424 { 425 struct dirent *pDirent = (struct dirent*) pInfo; 426 427 nSize = pDirent->d_size; 428 429 aDateCreated = MsDos2Date( (FDATE*) &pDirent->d_date ); 430 aTimeCreated = MsDos2Time( (FTIME*) &pDirent->d_time ); 431 aDateModified = aDateModified; 432 aTimeModified = aTimeModified; 433 aDateAccessed = aDateModified; 434 aTimeAccessed = aTimeModified; 435 436 nKindFlags = FSYS_KIND_FILE; 437 if ( pDirent->d_type & DOS_DIRECT ) 438 nKindFlags = FSYS_KIND_DIR; 439 } 440 441 /************************************************************************* 442 |* 443 |* FileStat::Update() 444 |* 445 |* Beschreibung FSYS.SDW 446 |* Ersterstellung MI 11.06.91 447 |* Letzte Aenderung MA 07.11.91 448 |* 449 *************************************************************************/ 450 451 struct _FSYS_FSQBUFFER 452 { 453 FSQBUFFER2 aBuf; 454 UCHAR sBuf[256]; 455 }; 456 457 BOOL FileStat::Update( const DirEntry& rDirEntry, BOOL bAccessRemovableDevice ) 458 { 459 nSize = 0; 460 FSysPathStyle eStyle = FSYS_STYLE_UNKNOWN; 461 aCreator.Erase(); 462 aType.Erase(); 463 aDateCreated = Date(0); 464 aTimeCreated = Time(0); 465 aDateModified = Date(0); 466 aTimeModified = Time(0); 467 aDateAccessed = Date(0); 468 aTimeAccessed = Time(0); 469 470 if ( !rDirEntry.IsValid() ) 471 { 472 nError = FSYS_ERR_NOTEXISTS; 473 return FALSE; 474 } 475 476 // Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt 477 if ( !rDirEntry.aName.Len() && rDirEntry.eFlag == FSYS_FLAG_ABSROOT ) 478 { 479 nKindFlags = FSYS_KIND_DIR; 480 nError = FSYS_ERR_OK; 481 return TRUE; 482 } 483 484 // Sonderbehandlung falls es sich um eine Wildcard handelt 485 ByteString aTempName( rDirEntry.GetName(), osl_getThreadTextEncoding() ); 486 if ( strchr( aTempName.GetBuffer(), '?' ) || 487 strchr( aTempName.GetBuffer(), '*' ) || 488 strchr( aTempName.GetBuffer(), ';' ) ) 489 { 490 nKindFlags = FSYS_KIND_WILD; 491 nError = FSYS_ERR_OK; 492 return TRUE; 493 } 494 495 // Sonderbehandlung falls es sich um eine Root handelt 496 if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME || 497 rDirEntry.eFlag == FSYS_FLAG_ABSROOT ) 498 { 499 if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME ) 500 nKindFlags = FSYS_KIND_DEV; 501 else 502 nKindFlags = FSYS_KIND_DIR; 503 504 if ( rDirEntry.aName.Len() == 2 ) 505 { 506 if ( !bDriveMap ) 507 CreateDriveMapImpl(); 508 509 ByteString rDirEntryUpperCase = ByteString( rDirEntry.aName ).ToUpperAscii(); 510 DriveMapItem &rItem = aDriveMap[rDirEntryUpperCase.GetChar(0) - 'A']; 511 if ( !rItem.nKind ) 512 { 513 nError = ERRCODE_IO_INVALIDDEVICE; 514 nKindFlags = FSYS_KIND_UNKNOWN; 515 return FALSE; 516 } 517 else 518 { 519 if ( rDirEntry.eFlag == FSYS_FLAG_VOLUME ) 520 nKindFlags |= FSYS_KIND_BLOCK | rItem.nKind; 521 eStyle = rItem.nStyle; 522 } 523 } 524 525 nError = FSYS_ERR_OK; 526 return TRUE; 527 } 528 529 // disable error-boxes for hard-errors 530 DosError(FERR_DISABLEHARDERR); 531 532 // Statusinformation vom Betriebssystem holen 533 DirEntry aTempDirEntry( rDirEntry ); 534 char* p; 535 536 aTempDirEntry.ToAbs(); 537 ByteString aFullName( aTempDirEntry.GetFull(), osl_getThreadTextEncoding() ); 538 539 #if 0 // YD 540 if (Folder::IsAvailable() && aTempDirEntry.IsLongNameOnFAT()) 541 { 542 // in String mit kurzem Pfad wandeln 543 ItemIDPath aItemIDPath(aTempDirEntry.GetFull()); 544 aFullName = ByteString( aItemIDPath.GetHostNotationPath(), osl_getThreadTextEncoding() ); 545 } 546 #endif 547 548 p = (char *) aFullName.GetBuffer(); 549 550 FILESTATUS3 filestat; 551 memset( &filestat, 0, sizeof( filestat ) ); 552 if( DosQueryPathInfo( (PSZ)p, 1, &filestat, sizeof( filestat ) ) ) 553 { 554 nError = FSYS_ERR_NOTEXISTS; 555 nKindFlags = FSYS_KIND_UNKNOWN; 556 return FALSE; 557 } 558 559 nError = FSYS_ERR_OK; 560 nSize = filestat.cbFile; 561 562 nKindFlags = FSYS_KIND_UNKNOWN; 563 if( filestat.attrFile & FILE_DIRECTORY ) 564 nKindFlags |= FSYS_KIND_DIR; 565 if ( nKindFlags == FSYS_KIND_UNKNOWN ) 566 nKindFlags = nKindFlags | FSYS_KIND_FILE; 567 568 aDateModified = Date( filestat.fdateLastWrite.day, 569 filestat.fdateLastWrite.month, 570 filestat.fdateLastWrite.year + 1980 ); 571 572 aTimeModified = Time( filestat.ftimeLastWrite.hours, 573 filestat.ftimeLastWrite.minutes, 574 filestat.ftimeLastWrite.twosecs*2 ); 575 576 if ( filestat.fdateCreation.day ) 577 { 578 aDateCreated = Date( filestat.fdateCreation.day, 579 filestat.fdateCreation.month, 580 filestat.fdateCreation.year + 1980 ); 581 582 aTimeCreated = Time( filestat.ftimeCreation.hours, 583 filestat.ftimeCreation.minutes, 584 filestat.ftimeCreation.twosecs*2 ); 585 } 586 else 587 { 588 aDateCreated = aDateModified; 589 aTimeCreated = aTimeModified; 590 } 591 592 if ( filestat.fdateLastAccess.day > 0 ) 593 { 594 aDateAccessed = Date( filestat.fdateLastAccess.day, 595 filestat.fdateLastAccess.month, 596 filestat.fdateLastAccess.year + 1980 ); 597 598 aTimeAccessed = Time( filestat.ftimeLastAccess.hours, 599 filestat.ftimeLastAccess.minutes, 600 filestat.ftimeLastAccess.twosecs*2 ); 601 } 602 else 603 { 604 aDateAccessed = aDateModified; 605 aTimeAccessed = aTimeModified; 606 } 607 608 return TRUE; 609 } 610 611 BOOL IsRedirectable_Impl( const ByteString &rPath ) 612 { 613 if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] ) 614 { 615 ByteString aVolume = rPath.Copy( 0, 3 ); 616 DriveMapItem &rItem = aDriveMap[toupper(aVolume.GetChar(0)) - 'A']; 617 return FSYS_KIND_FIXED != rItem.nKind; 618 } 619 return FALSE; 620 } 621 622 #if 0 623 BOOL IsRedirectable_Impl( const String &rPath ) 624 { 625 if ( rPath.Len() >= 3 && ':' == rPath.GetStr()[1] ) 626 { 627 DriveMapItem &rItem = aDriveMap[toupper(rPath[0]) - 'A']; 628 return FSYS_KIND_FIXED != rItem.nKind; 629 } 630 return FALSE; 631 } 632 #endif 633 634 635 /************************************************************************* 636 |* 637 |* TempDirImpl() 638 |* 639 |* Beschreibung liefert den Namens des Directories fuer temporaere 640 |* Dateien 641 |* Ersterstellung MI 16.03.94 642 |* Letzte Aenderung MI 16.03.94 643 |* 644 *************************************************************************/ 645 646 const char* TempDirImpl( char *pBuf ) 647 { 648 PSZ pVar; 649 USHORT nRet; 650 BOOL bAppendTemp = FALSE; // mu\s noch \\temp angeh"angt werden 651 652 // Erstmal sehen, ob TEMP oder TMP gesetzt sind 653 nRet = DosScanEnv( (PSZ)"TEMP", &pVar ); 654 if( nRet ) 655 nRet = DosScanEnv( (PSZ)"temp", &pVar ); 656 if( nRet ) 657 nRet = DosScanEnv( (PSZ)"TMP", &pVar ); 658 if( nRet ) 659 nRet = DosScanEnv( (PSZ)"tmp", &pVar ); 660 if( nRet ) 661 nRet = DosScanEnv( (PSZ)"TMPDIR", &pVar ); 662 663 // falls das geklappt hat, und ein Backslash dranhaengt, 664 // oder falls es bisher nicht geklappt hat, 665 // muessen wir nachher einen Backslash entfernen 666 BOOL bRemoveBS = nRet || *(pVar+strlen(pVar)-1) == '\\'; 667 668 // Keine temp-Variable gefunden, dann gehen wir mal auf die Suche 669 // nach dem System-Laufwerk 670 if( nRet ) 671 { 672 nRet = DosScanEnv( (PSZ)"USER_INI",&pVar ); 673 bAppendTemp = (0 == nRet); 674 } 675 if( nRet ) 676 { 677 nRet = DosScanEnv( (PSZ)"SYSTEM_INI", &pVar ); 678 bAppendTemp = (0 == nRet); 679 } 680 if( nRet ) 681 // Wenn das immer noch nicht reicht nehmen wir eben die Root von C: 682 #ifdef __BORLANDC__ 683 pVar = (PSZ)"c:\\temp\\"; 684 #else 685 pVar = (PCSZ)"c:\\temp\\"; 686 #endif 687 strcpy( pBuf, (const char*)pVar ); 688 689 // jetzt haengt ggf. ein Backlash dran, den wir abschneiden, 690 // ggf. inklusive dahinter haengendem Dateinamen 691 if ( bRemoveBS ) 692 { 693 char *pTail = pBuf + strlen(pBuf) - 1; 694 for ( char cLast = *pTail; cLast != '\\'; cLast = *(--pTail) ) 695 *pTail = 0; 696 } 697 698 if ( bAppendTemp ) 699 strcat( pBuf, "\\temp" ); 700 DirEntry( pBuf ).MakeDir(); 701 702 return pBuf; 703 } 704 705 #define CURRENT_COUNTRY 0 706 #define NLS_CODEPAGE 850 707 708 /*==================================================================== 709 * CreateCaseMapImpl() 710 * creates a map of each character to convert to lower 711 *--------------------------------------------------------------------*/ 712 713 #if 0 714 void CreateCaseMapImpl() 715 { 716 // build a string starting with code 0 as first character upto 255 717 char sTemp[256]; 718 USHORT n; 719 720 for ( n = 0; n < 256; ++n ) 721 sTemp[n] = (char) n; 722 723 // convert string to upper case 724 COUNTRYCODE aCountry; 725 aCountry.country = CURRENT_COUNTRY; /* Country code */ 726 aCountry.codepage = NLS_CODEPAGE; /* Code page */ 727 DosMapCase( 255, &aCountry, sTemp+1 ); 728 729 // fill a global buffer starting with code 0 as first character upto 255 730 for ( n = 0; n < 256; ++n ) 731 sCaseMap[n] = (char) n; 732 733 // reorder by upper-code and store in a global buffer 734 for ( n = 255; n > 0; --n ) 735 // was this character converted? 736 if ( sTemp[n] != (char) n ) 737 // we found a convertion from upper to lower 738 sCaseMap[ (unsigned char) sTemp[n] ] = (char) n; 739 740 bCaseMap = TRUE; 741 } 742 743 String ToLowerImpl( const String& rSource ) 744 { 745 if ( !bCaseMap ) 746 CreateCaseMapImpl(); 747 748 // TH sagt: International ist zu langsam, also mit einer eigenen Map 749 ByteString aLower( rSource ); 750 for ( USHORT n = 0; n < aLower.Len(); ++n ) 751 aLower[n] = sCaseMap[ (unsigned char) aLower[n] ]; 752 return aLower; 753 } 754 #endif // 0 755 756 /*==================================================================== 757 * CreateDriveMapImpl() 758 * creates a map of drive-infos like FileSystem (style) and Kind (remote) 759 *--------------------------------------------------------------------*/ 760 typedef struct _FSQBUFFER_ 761 { 762 FSQBUFFER2 aBuf; 763 UCHAR sBuf[64]; 764 } FSQBUFFER_; 765 766 void CreateDriveMapImpl() 767 { 768 #ifdef POWERPC 769 // !!!!! Hack, da der untere Teil mit Beta 2 noch abstuertzt !!!!! 770 BYTE nFloppies = 1; 771 for ( USHORT nDrive = 0; nDrive < 26; ++nDrive ) 772 { 773 if ( nDrive < nFloppies ) 774 { 775 aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE; 776 aDriveMap[nDrive].nStyle = FSYS_STYLE_FAT; 777 } 778 else 779 { 780 aDriveMap[nDrive].nKind = FSYS_KIND_UNKNOWN; 781 aDriveMap[nDrive].nStyle = FSYS_STYLE_UNKNOWN; 782 } 783 } 784 785 aDriveMap[2].nKind = FSYS_KIND_FIXED; 786 aDriveMap[2].nStyle = FSYS_STYLE_FAT; 787 #else 788 FSQBUFFER_ aBuf; 789 ULONG nBufLen; 790 APIRET nRet; 791 USHORT nDrive; 792 793 // disable error-boxes for hard-errors 794 DosError(FERR_DISABLEHARDERR); 795 796 // determine number of floppy-drives 797 BYTE nFloppies; 798 nRet = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY ); 799 800 // reset the map 801 for ( nDrive = 0; nDrive < 26; ++nDrive ) 802 { 803 if ( nDrive < nFloppies ) 804 { 805 aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE; 806 aDriveMap[nDrive].nStyle = FSYS_STYLE_FAT; 807 } 808 else 809 { 810 aDriveMap[nDrive].nKind = FSYS_KIND_UNKNOWN; 811 aDriveMap[nDrive].nStyle = FSYS_STYLE_UNKNOWN; 812 } 813 } 814 815 // determine file-system via DosOpen/DocDevIOCtrl 816 for ( nDrive = 2; nDrive < 26; ++nDrive ) 817 { 818 // open drive 819 BOOL bFixed; 820 HFILE nDevHandle; 821 char pDriveName[3] = "#:"; 822 pDriveName[0] = nDrive+'a'; 823 ULONG nAction; 824 nRet = DosOpen( (PSZ) pDriveName, &nDevHandle, 825 &nAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS, 826 OPEN_FLAGS_DASD|OPEN_SHARE_DENYNONE|OPEN_ACCESS_READONLY, 827 0 ); 828 829 // exists? 830 if ( !nRet ) 831 { 832 // removeable? 833 BYTE nDriveId = nDrive; 834 ULONG nParaOutLen, nDataOutLen; 835 nRet = DosDevIOCtl(nDevHandle, 8, 0x20, 836 &nDriveId, sizeof(nDriveId), &nParaOutLen, 837 &bFixed, sizeof(bFixed), &nDataOutLen ); 838 839 // prepare the drive-map 840 if ( !nRet && !bFixed ) 841 aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE; 842 843 // close drive 844 DosClose(nDevHandle); 845 } 846 else if ( nRet == ERROR_NOT_READY ) 847 aDriveMap[nDrive].nKind = FSYS_KIND_REMOVEABLE | FSYS_KIND_CDROM; 848 } 849 850 // determine file-system via FSAttach 851 nRet = 0; 852 for ( USHORT n = 3; nRet != ERROR_NO_MORE_ITEMS; ++n ) 853 { 854 nBufLen = sizeof( aBuf ); 855 nRet = DosQueryFSAttach( 0, n, FSAIL_DRVNUMBER, 856 (_FSQBUFFER2*) &aBuf, &nBufLen ); 857 if ( !nRet ) 858 { 859 nDrive = toupper(aBuf.aBuf.szName[0]) - 'A'; 860 861 if ( aDriveMap[nDrive].nKind == FSYS_KIND_UNKNOWN ) 862 aDriveMap[nDrive].nKind = 863 aBuf.aBuf.iType == 3 ? FSYS_KIND_FIXED : 864 aBuf.aBuf.iType == 4 ? FSYS_KIND_REMOTE : 865 FSYS_KIND_UNKNOWN; 866 867 char *pType = (char*)(aBuf.aBuf.szName + aBuf.aBuf.cbName + 1); 868 aDriveMap[nDrive].nStyle = 869 strcmp( pType, "FAT" ) == 0 ? FSYS_STYLE_FAT : 870 strcmp( pType, "FAT32" ) == 0 ? FSYS_STYLE_VFAT : 871 strcmp( pType, "NTFS" ) == 0 ? FSYS_STYLE_NTFS : 872 strcmp( pType, "HPFS" ) == 0 ? FSYS_STYLE_HPFS : 873 strcmp( pType, "JFS" ) == 0 ? FSYS_STYLE_HPFS : 874 strcmp( pType, "RAMFS" ) == 0 ? FSYS_STYLE_HPFS : 875 strcmp( pType, "NDFS32" ) == 0 ? FSYS_STYLE_HPFS : 876 strcmp( pType, "NWFS" ) == 0 ? FSYS_STYLE_NWFS : 877 strcmp( pType, "EXT2" ) == 0 ? FSYS_STYLE_UNX : 878 strcmp( pType, "NFS" ) == 0 ? FSYS_STYLE_UNX : 879 FSYS_STYLE_UNKNOWN; 880 if ( strcmp( pType, "CDFS" ) == 0 ) 881 aDriveMap[nDrive].nKind = FSYS_KIND_CDROM|FSYS_KIND_REMOVEABLE; 882 } 883 } 884 #endif 885 886 bDriveMap = TRUE; 887 } 888 889 Time MsDos2Time( const time_t *pTimeT ) 890 { 891 tm *pTm = localtime( pTimeT ); 892 if ( pTm ) 893 return Time( pTm->tm_hour, pTm->tm_min, pTm->tm_sec ); 894 else 895 return Time(0); 896 } 897 898 Date MsDos2Date( const time_t *pTimeT ) 899 { 900 tm *pTm = localtime( pTimeT ); 901 if ( pTm ) 902 return Date( pTm->tm_mday, pTm->tm_mon + 1, pTm->tm_year ); 903 else 904 return Date(0); 905 } 906 907 /************************************************************************* 908 |* 909 |* DirEntry::GetPathStyle() const 910 |* 911 |* Beschreibung 912 |* Ersterstellung MI 11.05.95 913 |* Letzte Aenderung MI 11.05.95 914 |* 915 *************************************************************************/ 916 917 FSysPathStyle DirEntry::GetPathStyle( const String &rDevice ) 918 { 919 ByteString aRootDir(rDevice, osl_getThreadTextEncoding()); 920 // UNC-Pathname? 921 if ( aRootDir.Len()==0 || ( aRootDir.Len() > 1 && aRootDir.GetChar(1) != ':' ) ) 922 return FSYS_STYLE_UNKNOWN; 923 924 if ( !bDriveMap ) 925 CreateDriveMapImpl(); 926 return aDriveMap[toupper(aRootDir.GetChar(0)) - 'A'].nStyle; 927 } 928 929 /************************************************************************* 930 |* 931 |* DirEntry::IsCaseSensitive() const 932 |* 933 |* Beschreibung 934 |* Ersterstellung TPF 26.02.1999 935 |* Letzte Aenderung 936 |* 937 *************************************************************************/ 938 939 BOOL DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const 940 { 941 if (eFormatter==FSYS_STYLE_HOST) 942 { 943 if (GetPathStyle(GetDevice().GetName()) == FSYS_STYLE_UNX) 944 { 945 return TRUE; 946 } 947 else 948 { 949 return FALSE; 950 } 951 } 952 else 953 { 954 BOOL isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv 955 switch ( eFormatter ) 956 { 957 case FSYS_STYLE_MAC: 958 case FSYS_STYLE_FAT: 959 case FSYS_STYLE_VFAT: 960 case FSYS_STYLE_NTFS: 961 case FSYS_STYLE_NWFS: 962 case FSYS_STYLE_HPFS: 963 case FSYS_STYLE_DETECT: 964 { 965 isCaseSensitive = FALSE; 966 break; 967 } 968 case FSYS_STYLE_SYSV: 969 case FSYS_STYLE_BSD: 970 { 971 isCaseSensitive = TRUE; 972 break; 973 } 974 default: 975 { 976 isCaseSensitive = FALSE; // ich bin unter OS2, also ist der default im Zweifelsfall case insensitiv 977 break; 978 } 979 } 980 return isCaseSensitive; 981 } 982 } 983 984 985 986 987 //========================================================================= 988 989 ErrCode FileStat::QueryDiskSpace( const String &rPath, 990 BigInt &rFreeBytes, BigInt &rTotalBytes ) 991 { 992 FSALLOCATE aFSInfoBuf; 993 ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding()); 994 ULONG nDriveNumber = toupper( aVol.GetChar(0) ) - 'A' + 1; 995 996 APIRET rc = DosQueryFSInfo( nDriveNumber, FSIL_ALLOC, 997 &aFSInfoBuf, sizeof(aFSInfoBuf) ); 998 if ( rc ) 999 return Sys2SolarError_Impl( rc ); 1000 1001 BigInt aBytesPerCluster( BigInt(aFSInfoBuf.cbSector) * 1002 BigInt(aFSInfoBuf.cSectorUnit) ); 1003 rFreeBytes = aBytesPerCluster * BigInt(aFSInfoBuf.cUnitAvail); 1004 rTotalBytes = aBytesPerCluster * BigInt(aFSInfoBuf.cUnit); 1005 return 0; 1006 } 1007 1008 //========================================================================= 1009 1010 void FSysEnableSysErrorBox( BOOL bEnable ) 1011 { 1012 DosError( bEnable ? 0 : FERR_DISABLEHARDERR ); 1013 } 1014 1015