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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_tools.hxx" 26 27 #ifdef _MSC_VER 28 #pragma warning (push,1) 29 #endif 30 #include <stdio.h> 31 #include <ctype.h> 32 #include <limits.h> 33 #ifdef _MSC_VER 34 #pragma warning (pop) 35 #endif 36 37 #include "wntmsc.hxx" 38 #include <tools/errinf.hxx> 39 #include <tools/debug.hxx> 40 #include <tools/list.hxx> 41 #include <tools/wldcrd.hxx> 42 #include <tools/fsys.hxx> 43 #include <tools/bigint.hxx> 44 45 DECLARE_LIST( DirEntryList, DirEntry* ); 46 DECLARE_LIST( FSysSortList, FSysSort* ); 47 DECLARE_LIST( FileStatList, FileStat* ); 48 49 int Sys2SolarError_Impl( int nSysErr ); 50 51 static sal_Bool bLastCaseSensitive = sal_False; 52 53 //-------------------------------------------------------------------- 54 55 ByteString Upper_Impl( const ByteString &rStr ) 56 { 57 ByteString aRet( rStr.GetBuffer() ); // es muss ein neuer String entstehen! 58 CharUpperBuff( (char*) aRet.GetBuffer(), aRet.Len() ); 59 return aRet; 60 } 61 62 //-------------------------------------------------------------------- 63 64 DIR *opendir( const char* pPfad ) 65 { 66 DIR *pDir = new DIR; 67 if ( pDir ) 68 pDir->p = (char*) pPfad; 69 return pDir; 70 } 71 72 struct dirent *readdir( DIR *pDir ) 73 { 74 bool bOk = false; 75 if ( pDir->p ) 76 { 77 char *pBuf = new char[ strlen( pDir->p ) + 5 ]; 78 if ( pBuf ) 79 { 80 // *.* dahinter, ggf mit "\\" abtrennen (falls nicht schon da) 81 strcpy( pBuf, pDir->p ); 82 strcat( pBuf, "\\*.*" + ( *(pBuf + strlen( pBuf ) - 1 ) == '\\' ) ); 83 CharUpperBuff( pBuf, strlen(pBuf) ); 84 pDir->h = FindFirstFile( pBuf, &pDir->aDirEnt ); 85 bOk = pDir->h != INVALID_HANDLE_VALUE; 86 pDir->p = NULL; 87 delete [] pBuf; 88 } 89 else 90 pDir->h = INVALID_HANDLE_VALUE; 91 } 92 else 93 { 94 bOk = FindNextFile( pDir->h, &pDir->aDirEnt ); 95 } 96 97 return bOk ? &pDir->aDirEnt : NULL; 98 } 99 100 int closedir( DIR *pDir ) 101 { 102 sal_Bool bOk = sal_False; 103 if ( pDir ) 104 { 105 bOk = 0 != pDir->p || FindClose( pDir->h ); 106 delete pDir; 107 } 108 return bOk; 109 } 110 111 /************************************************************************* 112 |* 113 |* DirEntry::GetPathStyle() const 114 |* 115 |* Beschreibung 116 |* Ersterstellung MI 11.05.95 117 |* Letzte Aenderung MI 11.05.95 118 |* 119 *************************************************************************/ 120 121 ErrCode GetPathStyle_Impl( const String &rDevice, FSysPathStyle &rStyle ) 122 { 123 ByteString aRootDir(rDevice, osl_getThreadTextEncoding()); 124 if ( aRootDir.Len() && aRootDir.GetBuffer()[aRootDir.Len()-1] != '\\' ) 125 aRootDir += '\\'; 126 127 char sVolumeName[256]; 128 char sFileSysName[16]; 129 DWORD nSerial[2]; 130 DWORD nMaxCompLen[2]; 131 DWORD nFlags[2]; 132 133 // Windows95 hat VFAT, WindowsNT nicht 134 DWORD nVer = GetVersion(); 135 sal_Bool bW95 = ( nVer & 0xFF ) >= 4; 136 137 FSysFailOnErrorImpl(); 138 rStyle = FSYS_STYLE_UNKNOWN; 139 if ( GetVolumeInformation( 140 (char*) aRootDir.GetBuffer(), 141 sVolumeName, 256, (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen, 142 (LPDWORD) &nFlags, sFileSysName, 16 ) ) 143 { 144 // FAT/VFAT? 145 if ( 0 == strcmp( "FAT", sFileSysName ) ) 146 rStyle = bW95 ? FSYS_STYLE_VFAT : FSYS_STYLE_FAT; 147 148 // NTFS? 149 else if ( 0 == strcmp( "NTFS", sFileSysName ) ) 150 rStyle = FSYS_STYLE_NTFS; 151 152 // HPFS? 153 else if ( 0 == strcmp( "HPFS", sFileSysName ) ) 154 rStyle = FSYS_STYLE_HPFS; 155 156 // NWCOMPA/NWFS? 157 else if ( 0 == strncmp( "NW", sFileSysName, 2 ) ) 158 rStyle = FSYS_STYLE_NWFS; 159 160 return ERRCODE_NONE; 161 } 162 163 return ERRCODE_IO_INVALIDDEVICE; 164 } 165 166 FSysPathStyle DirEntry::GetPathStyle( const String &rDevice ) 167 { 168 169 FSysPathStyle eStyle; 170 GetPathStyle_Impl( rDevice, eStyle ); 171 return eStyle; 172 } 173 174 /************************************************************************* 175 |* 176 |* DirEntry::IsCaseSensitive() 177 |* 178 |* Beschreibung FSYS.SDW 179 |* Ersterstellung MI 10.06.93 180 |* Letzte Aenderung TPF 26.02.1999 181 |* 182 *************************************************************************/ 183 184 sal_Bool DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const 185 { 186 187 if (eFormatter==FSYS_STYLE_HOST) 188 { 189 /* 190 DirEntry aRoot(*this); 191 aRoot.ToAbs(); 192 aRoot = aRoot[Level()-1]; 193 String aRootDir = aRoot.GetFull(FSYS_STYLE_HOST, sal_True); 194 195 char sVolumeName[256]; 196 DWORD nVolumeSerial; 197 DWORD nMaxCompLen; 198 DWORD nFlags; 199 char sFileSysName[16]; 200 201 if ( GetVolumeInformation( (char*) aRootDir.GetStr(), 202 sVolumeName, 203 256, 204 (LPDWORD) &nVolumeSerial, 205 (LPDWORD) &nMaxCompLen, 206 (LPDWORD) &nFlags, 207 sFileSysName, 208 16 )) 209 { 210 return (nFlags & FS_CASE_SENSITIVE) ? sal_True : sal_False; 211 } 212 else 213 { 214 return sal_False; 215 } 216 */ 217 // 218 // guter versuch, aber FS_CASE_SENSITIVE ist D?nnsinn in T?ten: 219 // 220 // sFileSysName FS_CASE_SENSITIVE 221 // FAT sal_False 222 // NTFS sal_True !!! 223 // NWCompat sal_False 224 // Samba sal_False 225 // 226 // NT spricht auch NTFS lediglich case preserving an, also ist unter NT alles case insensitiv 227 // 228 229 return sal_False; 230 } 231 else 232 { 233 sal_Bool isCaseSensitive = sal_False; // ich bin unter win32, also ist der default case insensitiv 234 switch ( eFormatter ) 235 { 236 case FSYS_STYLE_MAC: 237 case FSYS_STYLE_FAT: 238 case FSYS_STYLE_VFAT: 239 case FSYS_STYLE_NTFS: 240 case FSYS_STYLE_NWFS: 241 case FSYS_STYLE_HPFS: 242 case FSYS_STYLE_DETECT: 243 { 244 isCaseSensitive = sal_False; 245 break; 246 } 247 case FSYS_STYLE_SYSV: 248 case FSYS_STYLE_BSD: 249 { 250 isCaseSensitive = sal_True; 251 break; 252 } 253 default: 254 { 255 isCaseSensitive = sal_False; // ich bin unter win32, also ist der default case insensitiv 256 break; 257 } 258 } 259 return isCaseSensitive; 260 } 261 } 262 263 /************************************************************************* 264 |* 265 |* DirEntry::ToAbs() 266 |* 267 |* Beschreibung FSYS.SDW 268 |* Ersterstellung MI 26.04.91 269 |* Letzte Aenderung MA 02.12.91 270 |* 271 *************************************************************************/ 272 273 sal_Bool DirEntry::ToAbs() 274 { 275 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); 276 277 if ( FSYS_FLAG_VOLUME == eFlag ) 278 { 279 eFlag = FSYS_FLAG_ABSROOT; 280 return sal_True; 281 } 282 283 if ( IsAbs() ) 284 { 285 return sal_True; 286 } 287 288 289 char sBuf[256]; 290 char *pOld; 291 ByteString aFullName( GetFull(), osl_getThreadTextEncoding() ); 292 FSysFailOnErrorImpl(); 293 if ( GetFullPathName((char*)aFullName.GetBuffer(),256,sBuf,&pOld) > 511 ) 294 return sal_False; 295 296 *this = DirEntry( String(sBuf, osl_getThreadTextEncoding() )); 297 return sal_True; 298 } 299 300 301 /************************************************************************* 302 |* 303 |* DirEntry::GetVolume() 304 |* 305 |* Beschreibung FSYS.SDW 306 |* Ersterstellung MI 27.08.92 307 |* Letzte Aenderung MI 28.08.92 308 |* 309 *************************************************************************/ 310 311 String DirEntry::GetVolume() const 312 { 313 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); 314 315 String aRet; 316 const DirEntry *pTop = ImpGetTopPtr(); 317 ByteString aName = ByteString( pTop->aName ).ToLowerAscii(); 318 319 if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT || 320 pTop->eFlag == FSYS_FLAG_RELROOT || 321 pTop->eFlag == FSYS_FLAG_VOLUME ) 322 && aName != "a:" && aName != "b:" && Exists() ) 323 { 324 char sFileSysName[256]; 325 char sVolumeName[256]; 326 DWORD nVolumeNameLen = 256; 327 DWORD nSerial[2]; 328 DWORD nMaxCompLen[2]; 329 DWORD nFlags[2]; 330 ByteString aRootDir = pTop->aName; 331 FSysFailOnErrorImpl(); 332 333 // Network-Device zuerst probieren wegen langsamer Samba-Drives 334 if ( !WNetGetConnection( (char*) aRootDir.GetBuffer(), 335 sVolumeName, &nVolumeNameLen ) ) 336 aRet = String( sVolumeName, osl_getThreadTextEncoding()); 337 338 // dann den VolumeNamen fuer lokale Drives 339 if ( aRet.Len() == 0 ) 340 { 341 aRootDir += "\\"; 342 if ( GetVolumeInformation( (char*) aRootDir.GetBuffer(), 343 sVolumeName, 256, 344 (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen, 345 (LPDWORD) &nFlags, sFileSysName, 256 ) ) 346 aRet = String( sVolumeName, osl_getThreadTextEncoding()); 347 } 348 } 349 350 return aRet; 351 } 352 353 /************************************************************************* 354 |* 355 |* DirEntry::SetCWD() 356 |* 357 |* Beschreibung FSYS.SDW 358 |* Ersterstellung MI 26.04.91 359 |* Letzte Aenderung MI 21.05.92 360 |* 361 *************************************************************************/ 362 363 sal_Bool DirEntry::SetCWD( sal_Bool bSloppy ) const 364 { 365 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); 366 367 FSysFailOnErrorImpl(); 368 369 if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() ) 370 return sal_True; 371 372 if ( SetCurrentDirectory(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) ) 373 { 374 return sal_True; 375 } 376 377 if ( bSloppy && pParent && 378 SetCurrentDirectory(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) ) 379 { 380 return sal_True; 381 } 382 383 return sal_False; 384 } 385 386 //------------------------------------------------------------------------- 387 388 USHORT DirReader_Impl::Init() 389 { 390 // Block-Devices auflisten? 391 if ( pDir->eAttrMask & FSYS_KIND_BLOCK ) 392 { 393 // CWD merken 394 DirEntry aCurrentDir; 395 aCurrentDir.ToAbs(); 396 397 // einzeln auf Existenz und Masken-konformit"at pr"ufen 398 USHORT nRead = 0; 399 char sDrive[3] = { '?', ':', 0 }; 400 char sRoot[4] = { '?', ':', '\\', 0 }; 401 for ( char c = 'a'; c <= 'z'; c++ ) 402 { 403 sDrive[0] = c; 404 sRoot[0] = c; 405 DirEntry* pDrive = new DirEntry( sDrive, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST ); 406 if ( pDir->aNameMask.Matches( String( ByteString(sDrive), osl_getThreadTextEncoding())) && GetDriveType( sRoot ) != 1 ) 407 { 408 if ( pDir->pStatLst ) //Status fuer Sort gewuenscht? 409 { 410 FileStat *pNewStat = new FileStat( *pDrive ); 411 pDir->ImpSortedInsert( pDrive, pNewStat ); 412 } 413 else 414 pDir->ImpSortedInsert( pDrive, NULL ); 415 ++nRead; 416 } 417 else 418 delete pDrive; 419 } 420 421 // CWD restaurieren 422 aCurrentDir.SetCWD(); 423 return nRead; 424 } 425 426 return 0; 427 } 428 429 //------------------------------------------------------------------------- 430 431 USHORT DirReader_Impl::Read() 432 { 433 // Directories und Files auflisten? 434 if ( ( pDir->eAttrMask & FSYS_KIND_DIR || 435 pDir->eAttrMask & FSYS_KIND_FILE ) && 436 ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) ) 437 { 438 // Gross/Kleinschreibung nicht beruecksichtigen 439 ByteString aLowerName = pDosEntry->d_name; 440 CharLowerBuff( (char*) aLowerName.GetBuffer(), aLowerName.Len() ); 441 442 // Flags pruefen 443 sal_Bool bIsDirAndWantsDir = 444 ( ( pDir->eAttrMask & FSYS_KIND_DIR ) && 445 #ifdef ICC 446 ( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") || 447 strcmp(pDosEntry->d_name,"..")) ) ); 448 #else 449 ( pDosEntry->d_type & DOS_DIRECT ) ); 450 #endif 451 sal_Bool bIsFileAndWantsFile = 452 ( ( pDir->eAttrMask & FSYS_KIND_FILE ) && 453 #ifdef ICC 454 !( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") || 455 strcmp(pDosEntry->d_name,"..")) ) && 456 #else 457 !( pDosEntry->d_type & DOS_DIRECT ) && 458 #endif 459 !( pDosEntry->d_type & DOS_VOLUMEID ) ); 460 sal_Bool bIsHidden = (pDosEntry->d_type & _A_HIDDEN) != 0; 461 sal_Bool bWantsHidden = 0 == ( pDir->eAttrMask & FSYS_KIND_VISIBLE ); 462 if ( ( bIsDirAndWantsDir || bIsFileAndWantsFile ) && 463 ( bWantsHidden || !bIsHidden ) && 464 pDir->aNameMask.Matches( String(aLowerName, osl_getThreadTextEncoding()) ) ) 465 { 466 #ifdef DBG_UTIL 467 DbgOutf( "%s %s flags:%x found", 468 pDosEntry->d_name, 469 bIsFileAndWantsFile ? "file" : "dir", 470 pDosEntry->d_type ); 471 #endif 472 DirEntryFlag eFlag = 473 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT 474 : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT 475 : FSYS_FLAG_NORMAL; 476 DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name), 477 eFlag, FSYS_STYLE_NTFS ); 478 #ifdef FEAT_FSYS_DOUBLESPEED 479 pTemp->ImpSetStat( new FileStat( (void*) pDosDir, (void*) 0 ) ); 480 #endif 481 if ( pParent ) 482 pTemp->ImpChangeParent( new DirEntry( *pParent ), sal_False ); 483 if ( pDir->pStatLst ) //Status fuer Sort gewuenscht? 484 { 485 FileStat *pNewStat = new FileStat( (void*) pDosDir, (void*) 0 ); 486 pDir->ImpSortedInsert( pTemp, pNewStat ); 487 } 488 else 489 pDir->ImpSortedInsert( pTemp, NULL ); 490 return 1; 491 } 492 #ifdef DBG_UTIL 493 else 494 DbgOutf( "%s flags:%x skipped", 495 pDosEntry->d_name, 496 pDosEntry->d_type ); 497 #endif 498 499 } 500 else 501 bReady = sal_True; 502 return 0; 503 } 504 505 /************************************************************************* 506 |* 507 |* InitFileStat() 508 |* 509 |* Beschreibung gemeinsamer Teil der Ctoren fuer FileStat 510 |* Ersterstellung MI 28.08.92 511 |* Letzte Aenderung MI 28.08.92 512 |* 513 *************************************************************************/ 514 515 void FileStat::ImpInit( void* p ) 516 { 517 _WIN32_FIND_DATAA *pDirEnt = (_WIN32_FIND_DATAA*) p; 518 519 nError = FSYS_ERR_OK; 520 nSize = pDirEnt->nFileSizeLow; 521 522 SYSTEMTIME aSysTime; 523 FILETIME aLocTime; 524 525 // use the last write date / time when the creation date / time isn't set 526 if ( ( pDirEnt->ftCreationTime.dwLowDateTime == 0 ) && 527 ( pDirEnt->ftCreationTime.dwHighDateTime == 0 ) ) 528 { 529 pDirEnt->ftCreationTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime; 530 pDirEnt->ftCreationTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime; 531 } 532 533 // use the last write date / time when the last accessed date / time isn't set 534 if ( ( pDirEnt->ftLastAccessTime.dwLowDateTime == 0 ) && 535 ( pDirEnt->ftLastAccessTime.dwHighDateTime == 0 ) ) 536 { 537 pDirEnt->ftLastAccessTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime; 538 pDirEnt->ftLastAccessTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime; 539 } 540 541 FileTimeToLocalFileTime( &pDirEnt->ftCreationTime, &aLocTime ); 542 FileTimeToSystemTime( &aLocTime, &aSysTime ); 543 aDateCreated = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear ); 544 aTimeCreated = Time( aSysTime.wHour, aSysTime.wMinute, 545 aSysTime.wSecond, 0 ); 546 547 FileTimeToLocalFileTime( &pDirEnt->ftLastWriteTime, &aLocTime ); 548 FileTimeToSystemTime( &aLocTime, &aSysTime ); 549 aDateModified = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear ); 550 aTimeModified = Time( aSysTime.wHour, aSysTime.wMinute, 551 aSysTime.wSecond, 0 ); 552 553 FileTimeToLocalFileTime( &pDirEnt->ftLastAccessTime, &aLocTime ); 554 FileTimeToSystemTime( &aLocTime, &aSysTime ); 555 aDateAccessed = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear ); 556 aTimeAccessed = Time( aSysTime.wHour, aSysTime.wMinute, 557 aSysTime.wSecond, 0 ); 558 559 nKindFlags = FSYS_KIND_FILE; 560 if ( pDirEnt->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) 561 nKindFlags = FSYS_KIND_DIR; 562 } 563 564 /************************************************************************* 565 |* 566 |* FileStat::FileStat() 567 |* 568 |* Beschreibung FSYS.SDW 569 |* Ersterstellung MI 27.08.92 570 |* Letzte Aenderung MI 28.08.92 571 |* 572 *************************************************************************/ 573 574 FileStat::FileStat( const void *pInfo, // struct dirent 575 const void * ): // dummy 576 aDateCreated(0), 577 aTimeCreated(0), 578 aDateModified(0), 579 aTimeModified(0), 580 aDateAccessed(0), 581 aTimeAccessed(0) 582 { 583 ImpInit( ( (dirent*) pInfo ) ); 584 } 585 586 /************************************************************************* 587 |* 588 |* FileStat::Update() 589 |* 590 |* Beschreibung FSYS.SDW 591 |* Ersterstellung MI 27.08.92 592 |* Letzte Aenderung MI 28.08.92 593 |* 594 *************************************************************************/ 595 596 #ifdef _MSC_VER 597 #pragma warning(push, 1) 598 #pragma warning(disable: 4917) 599 #endif 600 #include <shlobj.h> 601 #ifdef _MSC_VER 602 #pragma warning(pop) 603 #endif 604 605 #ifdef UNICODE 606 #define lstrchr wcschr 607 #define lstrncmp wcsncmp 608 #else 609 #define lstrchr strchr 610 #define lstrncmp strncmp 611 #endif 612 613 //--------------------------------------------------------------------------- 614 615 void SHFreeMem( void *p ) 616 { 617 LPMALLOC pMalloc = NULL; 618 619 if ( SUCCEEDED(SHGetMalloc(&pMalloc)) ) 620 { 621 pMalloc->Free( p ); 622 pMalloc->Release(); 623 } 624 } 625 626 //--------------------------------------------------------------------------- 627 628 HRESULT SHGetIDListFromPath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl ) 629 { 630 if ( IsBadWritePtr(ppidl, sizeof(LPITEMIDLIST)) ) 631 return E_INVALIDARG; 632 633 LPSHELLFOLDER pDesktopFolder = NULL; 634 635 HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder ); 636 if ( FAILED(hResult) ) 637 return hResult; 638 639 ULONG chEaten = lstrlen( pszPath ); 640 DWORD dwAttributes = FILE_ATTRIBUTE_DIRECTORY; 641 642 #ifdef UNICODE 643 LPOLESTR wszPath = pszPath; 644 #else 645 WCHAR wszPath[MAX_PATH]; 646 MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszPath, -1, wszPath, MAX_PATH ); 647 #endif 648 649 hResult = pDesktopFolder->ParseDisplayName( hwndOwner, (LPBC)NULL, wszPath, &chEaten, ppidl, &dwAttributes ); 650 pDesktopFolder->Release(); 651 652 return hResult; 653 } 654 655 //--------------------------------------------------------------------------- 656 657 HRESULT SHGetFolderFromIDList( LPCITEMIDLIST pidl, LPSHELLFOLDER *ppFolder ) 658 { 659 if ( IsBadWritePtr(ppFolder, sizeof(LPSHELLFOLDER)) ) 660 return E_INVALIDARG; 661 662 *ppFolder = NULL; 663 664 LPSHELLFOLDER pDesktopFolder = NULL; 665 666 HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder ); 667 if ( FAILED(hResult) ) 668 return hResult; 669 670 hResult = pDesktopFolder->BindToObject( pidl, (LPBC)NULL, IID_IShellFolder, (LPVOID *)ppFolder ); 671 pDesktopFolder->Release(); 672 673 return hResult; 674 } 675 676 //--------------------------------------------------------------------------- 677 678 HRESULT SHResolvePath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl ) 679 { 680 // If hwndOwner is NULL, use the desktop window, because dialogs need a parent 681 682 #ifdef BOOTSTRAP 683 return NO_ERROR; 684 #else 685 if ( !hwndOwner ) 686 hwndOwner = GetDesktopWindow(); 687 688 HRESULT hResult = NOERROR; 689 LPTSTR pszPathCopy; 690 LPTSTR pszTrailingPath; 691 TCHAR cBackup = 0; 692 693 // First make a copy of the path 694 695 pszPathCopy = new TCHAR[lstrlen(pszPath) + 1]; 696 if ( pszPathCopy ) 697 lstrcpy( pszPathCopy, pszPath ); 698 else 699 return E_OUTOFMEMORY; 700 701 // Determine the first token 702 703 if ( !lstrncmp( pszPathCopy, "\\\\", 2 ) ) 704 pszTrailingPath = lstrchr( pszPathCopy + 2, '\\' ); 705 else 706 pszTrailingPath = lstrchr( pszPathCopy, '\\' ); 707 708 // Now scan the path tokens 709 710 while ( SUCCEEDED(hResult) ) 711 { 712 if ( pszTrailingPath ) 713 { 714 cBackup = *(++pszTrailingPath); 715 *pszTrailingPath = 0; 716 } 717 718 LPITEMIDLIST pidl = NULL; 719 720 // Make item ID list from leading path 721 722 hResult = SHGetIDListFromPath( hwndOwner, pszPathCopy, &pidl ); 723 724 // if path exists try to open it as folder 725 726 if ( SUCCEEDED(hResult) ) 727 { 728 // Only open the folder if it was not the last token 729 730 if ( pszTrailingPath ) 731 { 732 LPSHELLFOLDER pFolder; 733 734 // Create a folder instance 735 hResult = SHGetFolderFromIDList( pidl, &pFolder); 736 737 // Is it a folder ? 738 if ( SUCCEEDED(hResult) ) 739 { 740 // No try to instantiate an enumerator. 741 // This should popup a login dialog if any 742 743 LPENUMIDLIST pEnum = NULL; 744 745 hResult = pFolder->EnumObjects( hwndOwner, 746 SHCONTF_NONFOLDERS | SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN, 747 &pEnum ); 748 749 // Release the enumerator interface 750 if ( SUCCEEDED(hResult) ) 751 pEnum->Release(); 752 753 // Release the folder interface 754 pFolder->Release(); 755 } 756 757 SHFreeMem( pidl ); 758 } 759 else // It was the last token 760 { 761 if ( ppidl ) 762 *ppidl = pidl; 763 else 764 SHFreeMem( pidl ); 765 } 766 } 767 768 769 // Forward to next token 770 771 if ( pszTrailingPath ) 772 { 773 *pszTrailingPath = cBackup; 774 pszTrailingPath = lstrchr( pszTrailingPath, '\\' ); 775 } 776 else 777 break; 778 } 779 780 // Free the working copy of the path 781 delete pszPathCopy; 782 783 // NOERROR or OLE error code 784 return hResult; 785 #endif 786 } 787 788 //--------------------------------------------------------------------------- 789 // The Wrapper 790 //--------------------------------------------------------------------------- 791 792 sal_Bool Exists_Impl( const ByteString & crPath ) 793 { 794 // We do not know if OLE was initialized for this thread 795 796 CoInitialize( NULL ); 797 798 sal_Bool bSuccess = SUCCEEDED( SHResolvePath(NULL, crPath.GetBuffer(), NULL) ); 799 800 CoUninitialize(); 801 802 return bSuccess; 803 } 804 805 //--------------------------------------------------------------------------- 806 807 sal_Bool FileStat::Update( const DirEntry& rDirEntry, sal_Bool bForceAccess ) 808 { 809 nSize = 0; 810 nKindFlags = 0; 811 aCreator.Erase(); 812 aType.Erase(); 813 aDateCreated = Date(0); 814 aTimeCreated = Time(0); 815 aDateModified = Date(0); 816 aTimeModified = Time(0); 817 aDateAccessed = Date(0); 818 aTimeAccessed = Time(0); 819 820 if ( !rDirEntry.IsValid() ) 821 { 822 nError = FSYS_ERR_UNKNOWN; 823 nKindFlags = 0; 824 return sal_False; 825 } 826 827 // Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt 828 829 if ( !rDirEntry.aName.Len() && rDirEntry.eFlag == FSYS_FLAG_ABSROOT ) 830 { 831 nKindFlags = FSYS_KIND_DIR; 832 nError = FSYS_ERR_OK; 833 return sal_True; 834 } 835 836 // keine Error-Boxen anzeigen 837 FSysFailOnErrorImpl(); 838 839 // Redirect 840 String aPath( rDirEntry.GetFull() ); 841 #ifndef BOOTSTRAP 842 FSysRedirector::DoRedirect( aPath ); 843 #endif 844 DirEntry aDirEntry( aPath ); 845 846 // ist ein Medium im Laufwerk? 847 HACK("wie?") 848 sal_Bool bAccess = sal_True; 849 const DirEntry *pTop = aDirEntry.ImpGetTopPtr(); 850 ByteString aName = ByteString(pTop->aName).ToLowerAscii(); 851 if ( !bForceAccess && 852 ( pTop->eFlag == FSYS_FLAG_ABSROOT || 853 pTop->eFlag == FSYS_FLAG_RELROOT || 854 pTop->eFlag == FSYS_FLAG_VOLUME ) ) 855 if ( aName == "a:" || aName == "b:" ) 856 bAccess = sal_False; 857 else 858 DBG_TRACE( "FSys: will access removable device!" ); 859 if ( bAccess && ( aName == "a:" || aName == "b:" ) ) { 860 DBG_WARNING( "floppy will clatter" ); 861 } 862 863 // Sonderbehandlung, falls es sich um ein Volume handelt 864 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME || 865 aDirEntry.eFlag == FSYS_FLAG_ABSROOT ) 866 { 867 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ) 868 nKindFlags = FSYS_KIND_DEV | ( aDirEntry.aName.Len() == 2 869 ? FSYS_KIND_BLOCK 870 : FSYS_KIND_CHAR ); 871 else 872 nKindFlags = FSYS_KIND_DIR; 873 874 if ( !bAccess ) 875 { 876 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ) 877 nKindFlags |= FSYS_KIND_REMOVEABLE; 878 nError = FSYS_ERR_NOTEXISTS; 879 nKindFlags = 0; 880 return sal_False; 881 } 882 883 ByteString aRootDir = aDirEntry.aName; 884 aRootDir += ByteString( "\\" ); 885 UINT nType = GetDriveType( (char *) aRootDir.GetBuffer() ); //TPF: 2i 886 if ( nType == 1 || nType == 0 ) 887 { 888 nError = FSYS_ERR_NOTEXISTS; 889 nKindFlags = 0; 890 return sal_False; 891 } 892 893 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ) 894 nKindFlags = nKindFlags | 895 ( ( nType == DRIVE_REMOVABLE ) ? FSYS_KIND_REMOVEABLE : 0 ) | 896 ( ( nType == DRIVE_FIXED ) ? FSYS_KIND_FIXED : 0 ) | 897 ( ( nType == DRIVE_REMOTE ) ? FSYS_KIND_REMOTE : 0 ) | 898 ( ( nType == DRIVE_RAMDISK ) ? FSYS_KIND_RAM : 0 ) | 899 ( ( nType == DRIVE_CDROM ) ? FSYS_KIND_CDROM : 0 ) | 900 ( ( nType == 0 ) ? FSYS_KIND_UNKNOWN : 0 ); 901 902 nError = ERRCODE_NONE; 903 904 return sal_True; 905 } 906 907 // Statusinformation vom Betriebssystem holen 908 HANDLE h; //() 909 _WIN32_FIND_DATAA aEntry = {}; 910 DirEntry aAbsEntry( aDirEntry ); 911 if ( bAccess && aAbsEntry.ToAbs() ) 912 { 913 // im Namen k"onnen auch ';*?' als normale Zeichen vorkommen 914 ByteString aFilePath( aAbsEntry.GetFull(), osl_getThreadTextEncoding() ); 915 916 // MI: dann gehen Umlaute auf Novell-Servern nicht / wozu ueberhaupt 917 // CharUpperBuff( (char*) aFilePath.GetStr(), aFilePath.Len() ); 918 DBG_TRACE1( "FileStat: %s", aFilePath.GetBuffer() ); 919 h = aFilePath.Len() < 230 920 // die Win32-API ist hier sehr schwammig 921 ? FindFirstFile( (char *) aFilePath.GetBuffer(), &aEntry )//TPF: 2i 922 : INVALID_HANDLE_VALUE; 923 924 if ( INVALID_HANDLE_VALUE != h ) 925 { 926 if ( !( aEntry.dwFileAttributes & 0x40 ) ) // com1: etc. e.g. not encrypted (means normal) 927 { 928 ByteString aUpperName = Upper_Impl(ByteString(aAbsEntry.GetName(), osl_getThreadTextEncoding())); 929 930 // HRO: #74051# Compare also with short alternate filename 931 if ( aUpperName != Upper_Impl( aEntry.cFileName ) && aUpperName != Upper_Impl( aEntry.cAlternateFileName ) ) 932 h = INVALID_HANDLE_VALUE; 933 } 934 } 935 936 if ( INVALID_HANDLE_VALUE == h ) 937 { 938 DWORD dwError = GetLastError(); 939 940 if ( ERROR_BAD_NET_NAME == dwError ) 941 { 942 nKindFlags = FSYS_KIND_UNKNOWN; 943 nError = FSYS_ERR_NOTEXISTS; 944 return sal_False; 945 } 946 947 // UNC-Volume? 948 DirEntry *pTop = aAbsEntry.ImpGetTopPtr(); 949 if ( pTop->GetFlag() == FSYS_FLAG_ABSROOT && 950 ( pTop->aName.Len() > 1 && (pTop->aName.GetBuffer()[1] != ':' )) ) 951 { 952 if ( bForceAccess ) 953 { 954 if ( Exists_Impl( aFilePath ) ) 955 { 956 nKindFlags = FSYS_KIND_DIR|FSYS_KIND_REMOTE; 957 nError = FSYS_ERR_OK; 958 return sal_True; 959 } 960 else 961 { 962 nKindFlags = FSYS_KIND_UNKNOWN; 963 nError = FSYS_ERR_NOTEXISTS; 964 return sal_False; 965 } 966 } 967 } 968 } 969 } 970 else 971 h = INVALID_HANDLE_VALUE; 972 973 if ( h == INVALID_HANDLE_VALUE ) 974 { 975 // Sonderbehandlung falls es sich um eine Wildcard handelt 976 ByteString aTempName( aDirEntry.GetName(), osl_getThreadTextEncoding() ); 977 if ( strchr( aTempName.GetBuffer(), '?' ) || 978 strchr( aTempName.GetBuffer(), '*' ) || 979 strchr( aTempName.GetBuffer(), ';' ) ) 980 { 981 nKindFlags = FSYS_KIND_WILD; 982 nError = FSYS_ERR_OK; 983 return sal_True; 984 } 985 986 if ( bAccess ) 987 { 988 nError = FSYS_ERR_NOTEXISTS; 989 nKindFlags = FSYS_KIND_UNKNOWN; 990 } 991 else 992 nKindFlags = FSYS_KIND_REMOVEABLE; 993 } 994 else 995 { 996 ImpInit( &aEntry ); 997 FindClose( h ); 998 } 999 1000 if ( 0 != nError ) 1001 nKindFlags = 0; 1002 1003 return 0 == nError; 1004 1005 } 1006 1007 sal_Bool IsRedirectable_Impl( const ByteString &rPath ) 1008 { 1009 if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] ) 1010 { 1011 ByteString aVolume = rPath.Copy( 0, 3 ); 1012 UINT nType = GetDriveType( (char *) aVolume.GetBuffer() ); 1013 SetLastError( ERROR_SUCCESS ); 1014 return DRIVE_FIXED != nType; 1015 } 1016 return sal_False; 1017 } 1018 1019 /************************************************************************* 1020 |* 1021 |* TempDirImpl() 1022 |* 1023 |* Beschreibung liefert den Namens des Directories fuer temporaere 1024 |* Dateien 1025 |* Ersterstellung MI 16.03.94 1026 |* Letzte Aenderung MI 16.03.94 1027 |* 1028 *************************************************************************/ 1029 1030 const char* TempDirImpl( char *pBuf ) 1031 { 1032 if ( !GetTempPath( MAX_PATH, pBuf ) && 1033 !GetWindowsDirectory( pBuf, MAX_PATH ) && 1034 !GetEnvironmentVariable( "HOMEPATH", pBuf, MAX_PATH ) ) 1035 return 0; 1036 1037 return pBuf; 1038 } 1039 1040 //======================================================================= 1041 1042 ErrCode FileStat::QueryDiskSpace( const String &rPath, 1043 BigInt &rFreeBytes, BigInt &rTotalBytes ) 1044 { 1045 DWORD nSectorsPerCluster; /* address of sectors per cluster */ 1046 DWORD nBytesPerSector; /* address of bytes per sector */ 1047 DWORD nFreeClusters; /* address of number of free clusters */ 1048 DWORD nClusters; /* address of total number of clusters */ 1049 1050 ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding()); 1051 bool bOK = GetDiskFreeSpace( aVol.GetBuffer(), 1052 &nSectorsPerCluster, &nBytesPerSector, 1053 &nFreeClusters, &nClusters ); 1054 if ( !bOK ) 1055 return Sys2SolarError_Impl( GetLastError() ); 1056 1057 BigInt aBytesPerCluster( BigInt(nSectorsPerCluster) * 1058 BigInt(nBytesPerSector) ); 1059 rFreeBytes = aBytesPerCluster * BigInt(nFreeClusters); 1060 rTotalBytes = aBytesPerCluster * BigInt(nClusters); 1061 return 0; 1062 } 1063 1064 //========================================================================= 1065 1066 void FSysEnableSysErrorBox( sal_Bool bEnable ) 1067 { // Preserve other Bits!! 1068 sal_uInt32 nErrorMode = SetErrorMode( bEnable ? 0 : SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX ); 1069 if ( bEnable ) 1070 nErrorMode &= ~(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); 1071 else 1072 nErrorMode |= (SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); 1073 SetErrorMode( nErrorMode ); 1074 } 1075 1076 1077 1078