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