Update ooo320-m1
[ooovba.git] / tools / source / fsys / wntmsc.cxx
blob47985cd8b0d2a72b31d7a271f3455bedc2188720
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: wntmsc.cxx,v $
10 * $Revision: 1.10 $
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
34 #ifdef _MSC_VER
35 #pragma warning (push,1)
36 #endif
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <limits.h>
40 #ifdef _MSC_VER
41 #pragma warning (pop)
42 #endif
44 #include "wntmsc.hxx"
45 #include <tools/errinf.hxx>
46 #include <tools/debug.hxx>
47 #include <tools/list.hxx>
48 #include <tools/wldcrd.hxx>
49 #include <tools/fsys.hxx>
50 #include <tools/bigint.hxx>
52 DECLARE_LIST( DirEntryList, DirEntry* );
53 DECLARE_LIST( FSysSortList, FSysSort* );
54 DECLARE_LIST( FileStatList, FileStat* );
56 int Sys2SolarError_Impl( int nSysErr );
58 static BOOL bLastCaseSensitive = FALSE;
60 //--------------------------------------------------------------------
62 ByteString Upper_Impl( const ByteString &rStr )
64 ByteString aRet( rStr.GetBuffer() ); // es muss ein neuer String entstehen!
65 CharUpperBuff( (char*) aRet.GetBuffer(), aRet.Len() );
66 return aRet;
69 //--------------------------------------------------------------------
71 DIR *opendir( const char* pPfad )
73 DIR *pDir = new DIR;
74 if ( pDir )
75 pDir->p = (char*) pPfad;
76 return pDir;
79 struct dirent *readdir( DIR *pDir )
81 bool bOk = false;
82 if ( pDir->p )
84 char *pBuf = new char[ strlen( pDir->p ) + 5 ];
85 if ( pBuf )
87 // *.* dahinter, ggf mit "\\" abtrennen (falls nicht schon da)
88 strcpy( pBuf, pDir->p );
89 strcat( pBuf, "\\*.*" + ( *(pBuf + strlen( pBuf ) - 1 ) == '\\' ) );
90 CharUpperBuff( pBuf, strlen(pBuf) );
91 pDir->h = FindFirstFile( pBuf, &pDir->aDirEnt );
92 bOk = pDir->h != INVALID_HANDLE_VALUE;
93 pDir->p = NULL;
94 delete pBuf;
96 else
97 pDir->h = INVALID_HANDLE_VALUE;
99 else
101 bOk = FindNextFile( pDir->h, &pDir->aDirEnt );
104 return bOk ? &pDir->aDirEnt : NULL;
107 int closedir( DIR *pDir )
109 BOOL bOk = FALSE;
110 if ( pDir )
112 bOk = 0 != pDir->p || FindClose( pDir->h );
113 delete pDir;
115 return bOk;
118 /*************************************************************************
120 |* DirEntry::GetPathStyle() const
122 |* Beschreibung
123 |* Ersterstellung MI 11.05.95
124 |* Letzte Aenderung MI 11.05.95
126 *************************************************************************/
128 ErrCode GetPathStyle_Impl( const String &rDevice, FSysPathStyle &rStyle )
130 ByteString aRootDir(rDevice, osl_getThreadTextEncoding());
131 if ( aRootDir.Len() && aRootDir.GetBuffer()[aRootDir.Len()-1] != '\\' )
132 aRootDir += '\\';
134 char sVolumeName[256];
135 char sFileSysName[16];
136 DWORD nSerial[2];
137 DWORD nMaxCompLen[2];
138 DWORD nFlags[2];
140 // Windows95 hat VFAT, WindowsNT nicht
141 DWORD nVer = GetVersion();
142 BOOL bW95 = ( nVer & 0xFF ) >= 4;
144 FSysFailOnErrorImpl();
145 rStyle = FSYS_STYLE_UNKNOWN;
146 if ( GetVolumeInformation(
147 (char*) aRootDir.GetBuffer(),
148 sVolumeName, 256, (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen,
149 (LPDWORD) &nFlags, sFileSysName, 16 ) )
151 // FAT/VFAT?
152 if ( 0 == strcmp( "FAT", sFileSysName ) )
153 rStyle = bW95 ? FSYS_STYLE_VFAT : FSYS_STYLE_FAT;
155 // NTFS?
156 else if ( 0 == strcmp( "NTFS", sFileSysName ) )
157 rStyle = FSYS_STYLE_NTFS;
159 // HPFS?
160 else if ( 0 == strcmp( "HPFS", sFileSysName ) )
161 rStyle = FSYS_STYLE_HPFS;
163 // NWCOMPA/NWFS?
164 else if ( 0 == strncmp( "NW", sFileSysName, 2 ) )
165 rStyle = FSYS_STYLE_NWFS;
167 return ERRCODE_NONE;
170 return ERRCODE_IO_INVALIDDEVICE;
173 FSysPathStyle DirEntry::GetPathStyle( const String &rDevice )
176 FSysPathStyle eStyle;
177 GetPathStyle_Impl( rDevice, eStyle );
178 return eStyle;
181 /*************************************************************************
183 |* DirEntry::IsCaseSensitive()
185 |* Beschreibung FSYS.SDW
186 |* Ersterstellung MI 10.06.93
187 |* Letzte Aenderung TPF 26.02.1999
189 *************************************************************************/
191 BOOL DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const
194 if (eFormatter==FSYS_STYLE_HOST)
197 DirEntry aRoot(*this);
198 aRoot.ToAbs();
199 aRoot = aRoot[Level()-1];
200 String aRootDir = aRoot.GetFull(FSYS_STYLE_HOST, TRUE);
202 char sVolumeName[256];
203 DWORD nVolumeSerial;
204 DWORD nMaxCompLen;
205 DWORD nFlags;
206 char sFileSysName[16];
208 if ( GetVolumeInformation( (char*) aRootDir.GetStr(),
209 sVolumeName,
210 256,
211 (LPDWORD) &nVolumeSerial,
212 (LPDWORD) &nMaxCompLen,
213 (LPDWORD) &nFlags,
214 sFileSysName,
215 16 ))
217 return (nFlags & FS_CASE_SENSITIVE) ? TRUE : FALSE;
219 else
221 return FALSE;
225 // guter versuch, aber FS_CASE_SENSITIVE ist D?nnsinn in T?ten:
227 // sFileSysName FS_CASE_SENSITIVE
228 // FAT FALSE
229 // NTFS TRUE !!!
230 // NWCompat FALSE
231 // Samba FALSE
233 // NT spricht auch NTFS lediglich case preserving an, also ist unter NT alles case insensitiv
236 return FALSE;
238 else
240 BOOL isCaseSensitive = FALSE; // ich bin unter win32, also ist der default case insensitiv
241 switch ( eFormatter )
243 case FSYS_STYLE_MAC:
244 case FSYS_STYLE_FAT:
245 case FSYS_STYLE_VFAT:
246 case FSYS_STYLE_NTFS:
247 case FSYS_STYLE_NWFS:
248 case FSYS_STYLE_HPFS:
249 case FSYS_STYLE_DETECT:
251 isCaseSensitive = FALSE;
252 break;
254 case FSYS_STYLE_SYSV:
255 case FSYS_STYLE_BSD:
257 isCaseSensitive = TRUE;
258 break;
260 default:
262 isCaseSensitive = FALSE; // ich bin unter win32, also ist der default case insensitiv
263 break;
266 return isCaseSensitive;
270 /*************************************************************************
272 |* DirEntry::ToAbs()
274 |* Beschreibung FSYS.SDW
275 |* Ersterstellung MI 26.04.91
276 |* Letzte Aenderung MA 02.12.91
278 *************************************************************************/
280 BOOL DirEntry::ToAbs()
282 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
284 if ( FSYS_FLAG_VOLUME == eFlag )
286 eFlag = FSYS_FLAG_ABSROOT;
287 return TRUE;
290 if ( IsAbs() )
292 return TRUE;
296 char sBuf[256];
297 char *pOld;
298 ByteString aFullName( GetFull(), osl_getThreadTextEncoding() );
299 FSysFailOnErrorImpl();
300 if ( GetFullPathName((char*)aFullName.GetBuffer(),256,sBuf,&pOld) > 511 )
301 return FALSE;
303 *this = DirEntry( String(sBuf, osl_getThreadTextEncoding() ));
304 return TRUE;
308 /*************************************************************************
310 |* DirEntry::GetVolume()
312 |* Beschreibung FSYS.SDW
313 |* Ersterstellung MI 27.08.92
314 |* Letzte Aenderung MI 28.08.92
316 *************************************************************************/
318 String DirEntry::GetVolume() const
320 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
322 String aRet;
323 const DirEntry *pTop = ImpGetTopPtr();
324 ByteString aName = ByteString( pTop->aName ).ToLowerAscii();
326 if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT ||
327 pTop->eFlag == FSYS_FLAG_RELROOT ||
328 pTop->eFlag == FSYS_FLAG_VOLUME )
329 && aName != "a:" && aName != "b:" && Exists() )
331 char sFileSysName[256];
332 char sVolumeName[256];
333 DWORD nVolumeNameLen = 256;
334 DWORD nSerial[2];
335 DWORD nMaxCompLen[2];
336 DWORD nFlags[2];
337 ByteString aRootDir = pTop->aName;
338 FSysFailOnErrorImpl();
340 // Network-Device zuerst probieren wegen langsamer Samba-Drives
341 if ( !WNetGetConnection( (char*) aRootDir.GetBuffer(),
342 sVolumeName, &nVolumeNameLen ) )
343 aRet = String( sVolumeName, osl_getThreadTextEncoding());
345 // dann den VolumeNamen fuer lokale Drives
346 if ( aRet.Len() == 0 )
348 aRootDir += "\\";
349 if ( GetVolumeInformation( (char*) aRootDir.GetBuffer(),
350 sVolumeName, 256,
351 (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen,
352 (LPDWORD) &nFlags, sFileSysName, 256 ) )
353 aRet = String( sVolumeName, osl_getThreadTextEncoding());
357 return aRet;
360 /*************************************************************************
362 |* DirEntry::SetCWD()
364 |* Beschreibung FSYS.SDW
365 |* Ersterstellung MI 26.04.91
366 |* Letzte Aenderung MI 21.05.92
368 *************************************************************************/
370 BOOL DirEntry::SetCWD( BOOL bSloppy ) const
372 DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
374 FSysFailOnErrorImpl();
376 if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() )
377 return TRUE;
379 if ( SetCurrentDirectory(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
381 return TRUE;
384 if ( bSloppy && pParent &&
385 SetCurrentDirectory(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) )
387 return TRUE;
390 return FALSE;
393 //-------------------------------------------------------------------------
395 USHORT DirReader_Impl::Init()
397 // Block-Devices auflisten?
398 if ( pDir->eAttrMask & FSYS_KIND_BLOCK )
400 // CWD merken
401 DirEntry aCurrentDir;
402 aCurrentDir.ToAbs();
404 // einzeln auf Existenz und Masken-konformit"at pr"ufen
405 USHORT nRead = 0;
406 char sDrive[3] = { '?', ':', 0 };
407 char sRoot[4] = { '?', ':', '\\', 0 };
408 for ( char c = 'a'; c <= 'z'; c++ )
410 sDrive[0] = c;
411 sRoot[0] = c;
412 DirEntry* pDrive = new DirEntry( sDrive, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST );
413 if ( pDir->aNameMask.Matches( String( ByteString(sDrive), osl_getThreadTextEncoding())) && GetDriveType( sRoot ) != 1 )
415 if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
417 FileStat *pNewStat = new FileStat( *pDrive );
418 pDir->ImpSortedInsert( pDrive, pNewStat );
420 else
421 pDir->ImpSortedInsert( pDrive, NULL );
422 ++nRead;
424 else
425 delete pDrive;
428 // CWD restaurieren
429 aCurrentDir.SetCWD();
430 return nRead;
433 return 0;
436 //-------------------------------------------------------------------------
438 USHORT DirReader_Impl::Read()
440 // Directories und Files auflisten?
441 if ( ( pDir->eAttrMask & FSYS_KIND_DIR ||
442 pDir->eAttrMask & FSYS_KIND_FILE ) &&
443 ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) )
445 // Gross/Kleinschreibung nicht beruecksichtigen
446 ByteString aLowerName = pDosEntry->d_name;
447 CharLowerBuff( (char*) aLowerName.GetBuffer(), aLowerName.Len() );
449 // Flags pruefen
450 BOOL bIsDirAndWantsDir =
451 ( ( pDir->eAttrMask & FSYS_KIND_DIR ) &&
452 #ifdef ICC
453 ( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") ||
454 strcmp(pDosEntry->d_name,"..")) ) );
455 #else
456 ( pDosEntry->d_type & DOS_DIRECT ) );
457 #endif
458 BOOL bIsFileAndWantsFile =
459 ( ( pDir->eAttrMask & FSYS_KIND_FILE ) &&
460 #ifdef ICC
461 !( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") ||
462 strcmp(pDosEntry->d_name,"..")) ) &&
463 #else
464 !( pDosEntry->d_type & DOS_DIRECT ) &&
465 #endif
466 !( pDosEntry->d_type & DOS_VOLUMEID ) );
467 BOOL bIsHidden = (pDosEntry->d_type & _A_HIDDEN) != 0;
468 BOOL bWantsHidden = 0 == ( pDir->eAttrMask & FSYS_KIND_VISIBLE );
469 if ( ( bIsDirAndWantsDir || bIsFileAndWantsFile ) &&
470 ( bWantsHidden || !bIsHidden ) &&
471 pDir->aNameMask.Matches( String(aLowerName, osl_getThreadTextEncoding()) ) )
473 #ifdef DBG_UTIL
474 DbgOutf( "%s %s flags:%x found",
475 pDosEntry->d_name,
476 bIsFileAndWantsFile ? "file" : "dir",
477 pDosEntry->d_type );
478 #endif
479 DirEntryFlag eFlag =
480 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT
481 : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT
482 : FSYS_FLAG_NORMAL;
483 DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name),
484 eFlag, FSYS_STYLE_NTFS );
485 #ifdef FEAT_FSYS_DOUBLESPEED
486 pTemp->ImpSetStat( new FileStat( (void*) pDosDir, (void*) 0 ) );
487 #endif
488 if ( pParent )
489 pTemp->ImpChangeParent( new DirEntry( *pParent ), FALSE );
490 if ( pDir->pStatLst ) //Status fuer Sort gewuenscht?
492 FileStat *pNewStat = new FileStat( (void*) pDosDir, (void*) 0 );
493 pDir->ImpSortedInsert( pTemp, pNewStat );
495 else
496 pDir->ImpSortedInsert( pTemp, NULL );
497 return 1;
499 #ifdef DBG_UTIL
500 else
501 DbgOutf( "%s flags:%x skipped",
502 pDosEntry->d_name,
503 pDosEntry->d_type );
504 #endif
507 else
508 bReady = TRUE;
509 return 0;
512 /*************************************************************************
514 |* InitFileStat()
516 |* Beschreibung gemeinsamer Teil der Ctoren fuer FileStat
517 |* Ersterstellung MI 28.08.92
518 |* Letzte Aenderung MI 28.08.92
520 *************************************************************************/
522 void FileStat::ImpInit( void* p )
524 _WIN32_FIND_DATAA *pDirEnt = (_WIN32_FIND_DATAA*) p;
526 nError = FSYS_ERR_OK;
527 nSize = pDirEnt->nFileSizeLow;
529 SYSTEMTIME aSysTime;
530 FILETIME aLocTime;
532 // use the last write date / time when the creation date / time isn't set
533 if ( ( pDirEnt->ftCreationTime.dwLowDateTime == 0 ) &&
534 ( pDirEnt->ftCreationTime.dwHighDateTime == 0 ) )
536 pDirEnt->ftCreationTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime;
537 pDirEnt->ftCreationTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime;
540 // use the last write date / time when the last accessed date / time isn't set
541 if ( ( pDirEnt->ftLastAccessTime.dwLowDateTime == 0 ) &&
542 ( pDirEnt->ftLastAccessTime.dwHighDateTime == 0 ) )
544 pDirEnt->ftLastAccessTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime;
545 pDirEnt->ftLastAccessTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime;
548 FileTimeToLocalFileTime( &pDirEnt->ftCreationTime, &aLocTime );
549 FileTimeToSystemTime( &aLocTime, &aSysTime );
550 aDateCreated = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
551 aTimeCreated = Time( aSysTime.wHour, aSysTime.wMinute,
552 aSysTime.wSecond, 0 );
554 FileTimeToLocalFileTime( &pDirEnt->ftLastWriteTime, &aLocTime );
555 FileTimeToSystemTime( &aLocTime, &aSysTime );
556 aDateModified = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
557 aTimeModified = Time( aSysTime.wHour, aSysTime.wMinute,
558 aSysTime.wSecond, 0 );
560 FileTimeToLocalFileTime( &pDirEnt->ftLastAccessTime, &aLocTime );
561 FileTimeToSystemTime( &aLocTime, &aSysTime );
562 aDateAccessed = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear );
563 aTimeAccessed = Time( aSysTime.wHour, aSysTime.wMinute,
564 aSysTime.wSecond, 0 );
566 nKindFlags = FSYS_KIND_FILE;
567 if ( pDirEnt->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
568 nKindFlags = FSYS_KIND_DIR;
571 /*************************************************************************
573 |* FileStat::FileStat()
575 |* Beschreibung FSYS.SDW
576 |* Ersterstellung MI 27.08.92
577 |* Letzte Aenderung MI 28.08.92
579 *************************************************************************/
581 FileStat::FileStat( const void *pInfo, // struct dirent
582 const void * ): // dummy
583 aDateCreated(0),
584 aTimeCreated(0),
585 aDateModified(0),
586 aTimeModified(0),
587 aDateAccessed(0),
588 aTimeAccessed(0)
590 ImpInit( ( (dirent*) pInfo ) );
593 /*************************************************************************
595 |* FileStat::Update()
597 |* Beschreibung FSYS.SDW
598 |* Ersterstellung MI 27.08.92
599 |* Letzte Aenderung MI 28.08.92
601 *************************************************************************/
603 #ifdef _MSC_VER
604 #pragma warning(push, 1)
605 #pragma warning(disable: 4917)
606 #endif
607 #include <shlobj.h>
608 #ifdef _MSC_VER
609 #pragma warning(pop)
610 #endif
612 #ifdef UNICODE
613 #define lstrchr wcschr
614 #define lstrncmp wcsncmp
615 #else
616 #define lstrchr strchr
617 #define lstrncmp strncmp
618 #endif
620 //---------------------------------------------------------------------------
622 void SHFreeMem( void *p )
624 LPMALLOC pMalloc = NULL;
626 if ( SUCCEEDED(SHGetMalloc(&pMalloc)) )
628 pMalloc->Free( p );
629 pMalloc->Release();
633 //---------------------------------------------------------------------------
635 HRESULT SHGetIDListFromPath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl )
637 if ( IsBadWritePtr(ppidl, sizeof(LPITEMIDLIST)) )
638 return E_INVALIDARG;
640 LPSHELLFOLDER pDesktopFolder = NULL;
642 HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder );
643 if ( FAILED(hResult) )
644 return hResult;
646 ULONG chEaten = lstrlen( pszPath );
647 DWORD dwAttributes = FILE_ATTRIBUTE_DIRECTORY;
649 #ifdef UNICODE
650 LPOLESTR wszPath = pszPath;
651 #else
652 WCHAR wszPath[MAX_PATH];
653 MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszPath, -1, wszPath, MAX_PATH );
654 #endif
656 hResult = pDesktopFolder->ParseDisplayName( hwndOwner, (LPBC)NULL, wszPath, &chEaten, ppidl, &dwAttributes );
657 pDesktopFolder->Release();
659 return hResult;
662 //---------------------------------------------------------------------------
664 HRESULT SHGetFolderFromIDList( LPCITEMIDLIST pidl, LPSHELLFOLDER *ppFolder )
666 if ( IsBadWritePtr(ppFolder, sizeof(LPSHELLFOLDER)) )
667 return E_INVALIDARG;
669 *ppFolder = NULL;
671 LPSHELLFOLDER pDesktopFolder = NULL;
673 HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder );
674 if ( FAILED(hResult) )
675 return hResult;
677 hResult = pDesktopFolder->BindToObject( pidl, (LPBC)NULL, IID_IShellFolder, (LPVOID *)ppFolder );
678 pDesktopFolder->Release();
680 return hResult;
683 //---------------------------------------------------------------------------
685 HRESULT SHResolvePath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl )
687 // If hwndOwner is NULL, use the desktop window, because dialogs need a parent
689 #ifdef BOOTSTRAP
690 return NO_ERROR;
691 #else
692 if ( !hwndOwner )
693 hwndOwner = GetDesktopWindow();
695 HRESULT hResult = NOERROR;
696 LPTSTR pszPathCopy;
697 LPTSTR pszTrailingPath;
698 TCHAR cBackup = 0;
700 // First make a copy of the path
702 pszPathCopy = new TCHAR[lstrlen(pszPath) + 1];
703 if ( pszPathCopy )
704 lstrcpy( pszPathCopy, pszPath );
705 else
706 return E_OUTOFMEMORY;
708 // Determine the first token
710 if ( !lstrncmp( pszPathCopy, "\\\\", 2 ) )
711 pszTrailingPath = lstrchr( pszPathCopy + 2, '\\' );
712 else
713 pszTrailingPath = lstrchr( pszPathCopy, '\\' );
715 // Now scan the path tokens
717 while ( SUCCEEDED(hResult) )
719 if ( pszTrailingPath )
721 cBackup = *(++pszTrailingPath);
722 *pszTrailingPath = 0;
725 LPITEMIDLIST pidl = NULL;
727 // Make item ID list from leading path
729 hResult = SHGetIDListFromPath( hwndOwner, pszPathCopy, &pidl );
731 // if path exists try to open it as folder
733 if ( SUCCEEDED(hResult) )
735 // Only open the folder if it was not the last token
737 if ( pszTrailingPath )
739 LPSHELLFOLDER pFolder;
741 // Create a folder instance
742 hResult = SHGetFolderFromIDList( pidl, &pFolder);
744 // Is it a folder ?
745 if ( SUCCEEDED(hResult) )
747 // No try to instantiate an enumerator.
748 // This should popup a login dialog if any
750 LPENUMIDLIST pEnum = NULL;
752 hResult = pFolder->EnumObjects( hwndOwner,
753 SHCONTF_NONFOLDERS | SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN,
754 &pEnum );
756 // Release the enumerator interface
757 if ( SUCCEEDED(hResult) )
758 pEnum->Release();
760 // Release the folder interface
761 pFolder->Release();
764 SHFreeMem( pidl );
766 else // It was the last token
768 if ( ppidl )
769 *ppidl = pidl;
770 else
771 SHFreeMem( pidl );
776 // Forward to next token
778 if ( pszTrailingPath )
780 *pszTrailingPath = cBackup;
781 pszTrailingPath = lstrchr( pszTrailingPath, '\\' );
783 else
784 break;
787 // Free the working copy of the path
788 delete pszPathCopy;
790 // NOERROR or OLE error code
791 return hResult;
792 #endif
795 //---------------------------------------------------------------------------
796 // The Wrapper
797 //---------------------------------------------------------------------------
799 BOOL Exists_Impl( const ByteString & crPath )
801 // We do not know if OLE was initialized for this thread
803 CoInitialize( NULL );
805 BOOL bSuccess = SUCCEEDED( SHResolvePath(NULL, crPath.GetBuffer(), NULL) );
807 CoUninitialize();
809 return bSuccess;
812 //---------------------------------------------------------------------------
814 BOOL FileStat::Update( const DirEntry& rDirEntry, BOOL bForceAccess )
816 nSize = 0;
817 nKindFlags = 0;
818 aCreator.Erase();
819 aType.Erase();
820 aDateCreated = Date(0);
821 aTimeCreated = Time(0);
822 aDateModified = Date(0);
823 aTimeModified = Time(0);
824 aDateAccessed = Date(0);
825 aTimeAccessed = Time(0);
827 if ( !rDirEntry.IsValid() )
829 nError = FSYS_ERR_UNKNOWN;
830 nKindFlags = 0;
831 return FALSE;
834 // Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt
836 if ( !rDirEntry.aName.Len() && rDirEntry.eFlag == FSYS_FLAG_ABSROOT )
838 nKindFlags = FSYS_KIND_DIR;
839 nError = FSYS_ERR_OK;
840 return TRUE;
843 // keine Error-Boxen anzeigen
844 FSysFailOnErrorImpl();
846 // Redirect
847 String aPath( rDirEntry.GetFull() );
848 #ifndef BOOTSTRAP
849 FSysRedirector::DoRedirect( aPath );
850 #endif
851 DirEntry aDirEntry( aPath );
853 // ist ein Medium im Laufwerk?
854 HACK("wie?")
855 BOOL bAccess = TRUE;
856 const DirEntry *pTop = aDirEntry.ImpGetTopPtr();
857 ByteString aName = ByteString(pTop->aName).ToLowerAscii();
858 if ( !bForceAccess &&
859 ( pTop->eFlag == FSYS_FLAG_ABSROOT ||
860 pTop->eFlag == FSYS_FLAG_RELROOT ||
861 pTop->eFlag == FSYS_FLAG_VOLUME ) )
862 if ( aName == "a:" || aName == "b:" )
863 bAccess = FALSE;
864 else
865 DBG_TRACE( "FSys: will access removable device!" );
866 if ( bAccess && ( aName == "a:" || aName == "b:" ) ) {
867 DBG_WARNING( "floppy will clatter" );
870 // Sonderbehandlung, falls es sich um ein Volume handelt
871 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ||
872 aDirEntry.eFlag == FSYS_FLAG_ABSROOT )
874 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
875 nKindFlags = FSYS_KIND_DEV | ( aDirEntry.aName.Len() == 2
876 ? FSYS_KIND_BLOCK
877 : FSYS_KIND_CHAR );
878 else
879 nKindFlags = FSYS_KIND_DIR;
881 if ( !bAccess )
883 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
884 nKindFlags |= FSYS_KIND_REMOVEABLE;
885 nError = FSYS_ERR_NOTEXISTS;
886 nKindFlags = 0;
887 return FALSE;
890 ByteString aRootDir = aDirEntry.aName;
891 aRootDir += ByteString( "\\" );
892 UINT nType = GetDriveType( (char *) aRootDir.GetBuffer() ); //TPF: 2i
893 if ( nType == 1 || nType == 0 )
895 nError = FSYS_ERR_NOTEXISTS;
896 nKindFlags = 0;
897 return FALSE;
900 if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME )
901 nKindFlags = nKindFlags |
902 ( ( nType == DRIVE_REMOVABLE ) ? FSYS_KIND_REMOVEABLE : 0 ) |
903 ( ( nType == DRIVE_FIXED ) ? FSYS_KIND_FIXED : 0 ) |
904 ( ( nType == DRIVE_REMOTE ) ? FSYS_KIND_REMOTE : 0 ) |
905 ( ( nType == DRIVE_RAMDISK ) ? FSYS_KIND_RAM : 0 ) |
906 ( ( nType == DRIVE_CDROM ) ? FSYS_KIND_CDROM : 0 ) |
907 ( ( nType == 0 ) ? FSYS_KIND_UNKNOWN : 0 );
909 nError = ERRCODE_NONE;
911 return TRUE;
914 // Statusinformation vom Betriebssystem holen
915 HANDLE h; //()
916 _WIN32_FIND_DATAA aEntry = {};
917 DirEntry aAbsEntry( aDirEntry );
918 if ( bAccess && aAbsEntry.ToAbs() )
920 // im Namen k"onnen auch ';*?' als normale Zeichen vorkommen
921 ByteString aFilePath( aAbsEntry.GetFull(), osl_getThreadTextEncoding() );
923 // MI: dann gehen Umlaute auf Novell-Servern nicht / wozu ueberhaupt
924 // CharUpperBuff( (char*) aFilePath.GetStr(), aFilePath.Len() );
925 DBG_TRACE1( "FileStat: %s", aFilePath.GetBuffer() );
926 h = aFilePath.Len() < 230
927 // die Win32-API ist hier sehr schwammig
928 ? FindFirstFile( (char *) aFilePath.GetBuffer(), &aEntry )//TPF: 2i
929 : INVALID_HANDLE_VALUE;
931 if ( INVALID_HANDLE_VALUE != h )
933 if ( !( aEntry.dwFileAttributes & 0x40 ) ) // com1: etc. e.g. not encrypted (means normal)
935 ByteString aUpperName = Upper_Impl(ByteString(aAbsEntry.GetName(), osl_getThreadTextEncoding()));
937 // HRO: #74051# Compare also with short alternate filename
938 if ( aUpperName != Upper_Impl( aEntry.cFileName ) && aUpperName != Upper_Impl( aEntry.cAlternateFileName ) )
939 h = INVALID_HANDLE_VALUE;
943 if ( INVALID_HANDLE_VALUE == h )
945 DWORD dwError = GetLastError();
947 if ( ERROR_BAD_NET_NAME == dwError )
949 nKindFlags = FSYS_KIND_UNKNOWN;
950 nError = FSYS_ERR_NOTEXISTS;
951 return FALSE;
954 // UNC-Volume?
955 DirEntry *pTop = aAbsEntry.ImpGetTopPtr();
956 if ( pTop->GetFlag() == FSYS_FLAG_ABSROOT &&
957 ( pTop->aName.Len() > 1 && (pTop->aName.GetBuffer()[1] != ':' )) )
959 if ( bForceAccess )
961 if ( Exists_Impl( aFilePath ) )
963 nKindFlags = FSYS_KIND_DIR|FSYS_KIND_REMOTE;
964 nError = FSYS_ERR_OK;
965 return TRUE;
967 else
969 nKindFlags = FSYS_KIND_UNKNOWN;
970 nError = FSYS_ERR_NOTEXISTS;
971 return FALSE;
977 else
978 h = INVALID_HANDLE_VALUE;
980 if ( h == INVALID_HANDLE_VALUE )
982 // Sonderbehandlung falls es sich um eine Wildcard handelt
983 ByteString aTempName( aDirEntry.GetName(), osl_getThreadTextEncoding() );
984 if ( strchr( aTempName.GetBuffer(), '?' ) ||
985 strchr( aTempName.GetBuffer(), '*' ) ||
986 strchr( aTempName.GetBuffer(), ';' ) )
988 nKindFlags = FSYS_KIND_WILD;
989 nError = FSYS_ERR_OK;
990 return TRUE;
993 if ( bAccess )
995 nError = FSYS_ERR_NOTEXISTS;
996 nKindFlags = FSYS_KIND_UNKNOWN;
998 else
999 nKindFlags = FSYS_KIND_REMOVEABLE;
1001 else
1003 ImpInit( &aEntry );
1004 FindClose( h );
1007 if ( 0 != nError )
1008 nKindFlags = 0;
1010 return 0 == nError;
1014 BOOL IsRedirectable_Impl( const ByteString &rPath )
1016 if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] )
1018 ByteString aVolume = rPath.Copy( 0, 3 );
1019 UINT nType = GetDriveType( (char *) aVolume.GetBuffer() );
1020 SetLastError( ERROR_SUCCESS );
1021 return DRIVE_FIXED != nType;
1023 return FALSE;
1026 /*************************************************************************
1028 |* TempDirImpl()
1030 |* Beschreibung liefert den Namens des Directories fuer temporaere
1031 |* Dateien
1032 |* Ersterstellung MI 16.03.94
1033 |* Letzte Aenderung MI 16.03.94
1035 *************************************************************************/
1037 const char* TempDirImpl( char *pBuf )
1039 if ( !GetTempPath( MAX_PATH, pBuf ) &&
1040 !GetWindowsDirectory( pBuf, MAX_PATH ) &&
1041 !GetEnvironmentVariable( "HOMEPATH", pBuf, MAX_PATH ) )
1042 return 0;
1044 return pBuf;
1047 //=======================================================================
1049 ErrCode FileStat::QueryDiskSpace( const String &rPath,
1050 BigInt &rFreeBytes, BigInt &rTotalBytes )
1052 DWORD nSectorsPerCluster; /* address of sectors per cluster */
1053 DWORD nBytesPerSector; /* address of bytes per sector */
1054 DWORD nFreeClusters; /* address of number of free clusters */
1055 DWORD nClusters; /* address of total number of clusters */
1057 ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding());
1058 bool bOK = GetDiskFreeSpace( aVol.GetBuffer(),
1059 &nSectorsPerCluster, &nBytesPerSector,
1060 &nFreeClusters, &nClusters );
1061 if ( !bOK )
1062 return Sys2SolarError_Impl( GetLastError() );
1064 BigInt aBytesPerCluster( BigInt(nSectorsPerCluster) *
1065 BigInt(nBytesPerSector) );
1066 rFreeBytes = aBytesPerCluster * BigInt(nFreeClusters);
1067 rTotalBytes = aBytesPerCluster * BigInt(nClusters);
1068 return 0;
1071 //=========================================================================
1073 void FSysEnableSysErrorBox( BOOL bEnable )
1074 { // Preserve other Bits!!
1075 sal_uInt32 nErrorMode = SetErrorMode( bEnable ? 0 : SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX );
1076 if ( bEnable )
1077 nErrorMode &= ~(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
1078 else
1079 nErrorMode |= (SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
1080 SetErrorMode( nErrorMode );