| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_tools.hxx" |
| |
| #ifdef _MSC_VER |
| #pragma warning (push,1) |
| #endif |
| #include <stdio.h> |
| #include <ctype.h> |
| #include <limits.h> |
| #ifdef _MSC_VER |
| #pragma warning (pop) |
| #endif |
| |
| #include "wntmsc.hxx" |
| #include <tools/errinf.hxx> |
| #include <tools/debug.hxx> |
| #include <tools/list.hxx> |
| #include <tools/wldcrd.hxx> |
| #include <tools/fsys.hxx> |
| #include <tools/bigint.hxx> |
| |
| DECLARE_LIST( DirEntryList, DirEntry* ); |
| DECLARE_LIST( FSysSortList, FSysSort* ); |
| DECLARE_LIST( FileStatList, FileStat* ); |
| |
| int Sys2SolarError_Impl( int nSysErr ); |
| |
| static sal_Bool bLastCaseSensitive = sal_False; |
| |
| //-------------------------------------------------------------------- |
| |
| ByteString Upper_Impl( const ByteString &rStr ) |
| { |
| ByteString aRet( rStr.GetBuffer() ); // es muss ein neuer String entstehen! |
| CharUpperBuff( (char*) aRet.GetBuffer(), aRet.Len() ); |
| return aRet; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| DIR *opendir( const char* pPfad ) |
| { |
| DIR *pDir = new DIR; |
| if ( pDir ) |
| pDir->p = (char*) pPfad; |
| return pDir; |
| } |
| |
| struct dirent *readdir( DIR *pDir ) |
| { |
| bool bOk = false; |
| if ( pDir->p ) |
| { |
| char *pBuf = new char[ strlen( pDir->p ) + 5 ]; |
| if ( pBuf ) |
| { |
| // *.* dahinter, ggf mit "\\" abtrennen (falls nicht schon da) |
| strcpy( pBuf, pDir->p ); |
| strcat( pBuf, "\\*.*" + ( *(pBuf + strlen( pBuf ) - 1 ) == '\\' ) ); |
| CharUpperBuff( pBuf, strlen(pBuf) ); |
| pDir->h = FindFirstFile( pBuf, &pDir->aDirEnt ); |
| bOk = pDir->h != INVALID_HANDLE_VALUE; |
| pDir->p = NULL; |
| delete [] pBuf; |
| } |
| else |
| pDir->h = INVALID_HANDLE_VALUE; |
| } |
| else |
| { |
| bOk = FindNextFile( pDir->h, &pDir->aDirEnt ); |
| } |
| |
| return bOk ? &pDir->aDirEnt : NULL; |
| } |
| |
| int closedir( DIR *pDir ) |
| { |
| sal_Bool bOk = sal_False; |
| if ( pDir ) |
| { |
| bOk = 0 != pDir->p || FindClose( pDir->h ); |
| delete pDir; |
| } |
| return bOk; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetPathStyle() const |
| |* |
| |* Beschreibung |
| |* Ersterstellung MI 11.05.95 |
| |* Letzte Aenderung MI 11.05.95 |
| |* |
| *************************************************************************/ |
| |
| ErrCode GetPathStyle_Impl( const String &rDevice, FSysPathStyle &rStyle ) |
| { |
| ByteString aRootDir(rDevice, osl_getThreadTextEncoding()); |
| if ( aRootDir.Len() && aRootDir.GetBuffer()[aRootDir.Len()-1] != '\\' ) |
| aRootDir += '\\'; |
| |
| char sVolumeName[256]; |
| char sFileSysName[16]; |
| DWORD nSerial[2]; |
| DWORD nMaxCompLen[2]; |
| DWORD nFlags[2]; |
| |
| // Windows95 hat VFAT, WindowsNT nicht |
| DWORD nVer = GetVersion(); |
| sal_Bool bW95 = ( nVer & 0xFF ) >= 4; |
| |
| FSysFailOnErrorImpl(); |
| rStyle = FSYS_STYLE_UNKNOWN; |
| if ( GetVolumeInformation( |
| (char*) aRootDir.GetBuffer(), |
| sVolumeName, 256, (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen, |
| (LPDWORD) &nFlags, sFileSysName, 16 ) ) |
| { |
| // FAT/VFAT? |
| if ( 0 == strcmp( "FAT", sFileSysName ) ) |
| rStyle = bW95 ? FSYS_STYLE_VFAT : FSYS_STYLE_FAT; |
| |
| // NTFS? |
| else if ( 0 == strcmp( "NTFS", sFileSysName ) ) |
| rStyle = FSYS_STYLE_NTFS; |
| |
| // HPFS? |
| else if ( 0 == strcmp( "HPFS", sFileSysName ) ) |
| rStyle = FSYS_STYLE_HPFS; |
| |
| // NWCOMPA/NWFS? |
| else if ( 0 == strncmp( "NW", sFileSysName, 2 ) ) |
| rStyle = FSYS_STYLE_NWFS; |
| |
| return ERRCODE_NONE; |
| } |
| |
| return ERRCODE_IO_INVALIDDEVICE; |
| } |
| |
| FSysPathStyle DirEntry::GetPathStyle( const String &rDevice ) |
| { |
| |
| FSysPathStyle eStyle; |
| GetPathStyle_Impl( rDevice, eStyle ); |
| return eStyle; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::IsCaseSensitive() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 10.06.93 |
| |* Letzte Aenderung TPF 26.02.1999 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const |
| { |
| |
| if (eFormatter==FSYS_STYLE_HOST) |
| { |
| /* |
| DirEntry aRoot(*this); |
| aRoot.ToAbs(); |
| aRoot = aRoot[Level()-1]; |
| String aRootDir = aRoot.GetFull(FSYS_STYLE_HOST, sal_True); |
| |
| char sVolumeName[256]; |
| DWORD nVolumeSerial; |
| DWORD nMaxCompLen; |
| DWORD nFlags; |
| char sFileSysName[16]; |
| |
| if ( GetVolumeInformation( (char*) aRootDir.GetStr(), |
| sVolumeName, |
| 256, |
| (LPDWORD) &nVolumeSerial, |
| (LPDWORD) &nMaxCompLen, |
| (LPDWORD) &nFlags, |
| sFileSysName, |
| 16 )) |
| { |
| return (nFlags & FS_CASE_SENSITIVE) ? sal_True : sal_False; |
| } |
| else |
| { |
| return sal_False; |
| } |
| */ |
| // |
| // guter versuch, aber FS_CASE_SENSITIVE ist D?nnsinn in T?ten: |
| // |
| // sFileSysName FS_CASE_SENSITIVE |
| // FAT sal_False |
| // NTFS sal_True !!! |
| // NWCompat sal_False |
| // Samba sal_False |
| // |
| // NT spricht auch NTFS lediglich case preserving an, also ist unter NT alles case insensitiv |
| // |
| |
| return sal_False; |
| } |
| else |
| { |
| sal_Bool isCaseSensitive = sal_False; // ich bin unter win32, also ist der default case insensitiv |
| switch ( eFormatter ) |
| { |
| case FSYS_STYLE_MAC: |
| case FSYS_STYLE_FAT: |
| case FSYS_STYLE_VFAT: |
| case FSYS_STYLE_NTFS: |
| case FSYS_STYLE_NWFS: |
| case FSYS_STYLE_HPFS: |
| case FSYS_STYLE_DETECT: |
| { |
| isCaseSensitive = sal_False; |
| break; |
| } |
| case FSYS_STYLE_SYSV: |
| case FSYS_STYLE_BSD: |
| { |
| isCaseSensitive = sal_True; |
| break; |
| } |
| default: |
| { |
| isCaseSensitive = sal_False; // ich bin unter win32, also ist der default case insensitiv |
| break; |
| } |
| } |
| return isCaseSensitive; |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ToAbs() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::ToAbs() |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| if ( FSYS_FLAG_VOLUME == eFlag ) |
| { |
| eFlag = FSYS_FLAG_ABSROOT; |
| return sal_True; |
| } |
| |
| if ( IsAbs() ) |
| { |
| return sal_True; |
| } |
| |
| |
| char sBuf[256]; |
| char *pOld; |
| ByteString aFullName( GetFull(), osl_getThreadTextEncoding() ); |
| FSysFailOnErrorImpl(); |
| if ( GetFullPathName((char*)aFullName.GetBuffer(),256,sBuf,&pOld) > 511 ) |
| return sal_False; |
| |
| *this = DirEntry( String(sBuf, osl_getThreadTextEncoding() )); |
| return sal_True; |
| } |
| |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetVolume() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 27.08.92 |
| |* Letzte Aenderung MI 28.08.92 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::GetVolume() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| String aRet; |
| const DirEntry *pTop = ImpGetTopPtr(); |
| ByteString aName = ByteString( pTop->aName ).ToLowerAscii(); |
| |
| if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT || |
| pTop->eFlag == FSYS_FLAG_RELROOT || |
| pTop->eFlag == FSYS_FLAG_VOLUME ) |
| && aName != "a:" && aName != "b:" && Exists() ) |
| { |
| char sFileSysName[256]; |
| char sVolumeName[256]; |
| DWORD nVolumeNameLen = 256; |
| DWORD nSerial[2]; |
| DWORD nMaxCompLen[2]; |
| DWORD nFlags[2]; |
| ByteString aRootDir = pTop->aName; |
| FSysFailOnErrorImpl(); |
| |
| // Network-Device zuerst probieren wegen langsamer Samba-Drives |
| if ( !WNetGetConnection( (char*) aRootDir.GetBuffer(), |
| sVolumeName, &nVolumeNameLen ) ) |
| aRet = String( sVolumeName, osl_getThreadTextEncoding()); |
| |
| // dann den VolumeNamen fuer lokale Drives |
| if ( aRet.Len() == 0 ) |
| { |
| aRootDir += "\\"; |
| if ( GetVolumeInformation( (char*) aRootDir.GetBuffer(), |
| sVolumeName, 256, |
| (LPDWORD) &nSerial, (LPDWORD) &nMaxCompLen, |
| (LPDWORD) &nFlags, sFileSysName, 256 ) ) |
| aRet = String( sVolumeName, osl_getThreadTextEncoding()); |
| } |
| } |
| |
| return aRet; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::SetCWD() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 21.05.92 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::SetCWD( sal_Bool bSloppy ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| FSysFailOnErrorImpl(); |
| |
| if ( eFlag == FSYS_FLAG_CURRENT && !aName.Len() ) |
| return sal_True; |
| |
| if ( SetCurrentDirectory(ByteString(GetFull(), osl_getThreadTextEncoding()).GetBuffer()) ) |
| { |
| return sal_True; |
| } |
| |
| if ( bSloppy && pParent && |
| SetCurrentDirectory(ByteString(pParent->GetFull(), osl_getThreadTextEncoding()).GetBuffer()) ) |
| { |
| return sal_True; |
| } |
| |
| return sal_False; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| USHORT DirReader_Impl::Init() |
| { |
| // Block-Devices auflisten? |
| if ( pDir->eAttrMask & FSYS_KIND_BLOCK ) |
| { |
| // CWD merken |
| DirEntry aCurrentDir; |
| aCurrentDir.ToAbs(); |
| |
| // einzeln auf Existenz und Masken-konformit"at pr"ufen |
| USHORT nRead = 0; |
| char sDrive[3] = { '?', ':', 0 }; |
| char sRoot[4] = { '?', ':', '\\', 0 }; |
| for ( char c = 'a'; c <= 'z'; c++ ) |
| { |
| sDrive[0] = c; |
| sRoot[0] = c; |
| DirEntry* pDrive = new DirEntry( sDrive, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST ); |
| if ( pDir->aNameMask.Matches( String( ByteString(sDrive), osl_getThreadTextEncoding())) && GetDriveType( sRoot ) != 1 ) |
| { |
| if ( pDir->pStatLst ) //Status fuer Sort gewuenscht? |
| { |
| FileStat *pNewStat = new FileStat( *pDrive ); |
| pDir->ImpSortedInsert( pDrive, pNewStat ); |
| } |
| else |
| pDir->ImpSortedInsert( pDrive, NULL ); |
| ++nRead; |
| } |
| else |
| delete pDrive; |
| } |
| |
| // CWD restaurieren |
| aCurrentDir.SetCWD(); |
| return nRead; |
| } |
| |
| return 0; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| USHORT DirReader_Impl::Read() |
| { |
| // Directories und Files auflisten? |
| if ( ( pDir->eAttrMask & FSYS_KIND_DIR || |
| pDir->eAttrMask & FSYS_KIND_FILE ) && |
| ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) ) |
| { |
| // Gross/Kleinschreibung nicht beruecksichtigen |
| ByteString aLowerName = pDosEntry->d_name; |
| CharLowerBuff( (char*) aLowerName.GetBuffer(), aLowerName.Len() ); |
| |
| // Flags pruefen |
| sal_Bool bIsDirAndWantsDir = |
| ( ( pDir->eAttrMask & FSYS_KIND_DIR ) && |
| #ifdef ICC |
| ( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") || |
| strcmp(pDosEntry->d_name,"..")) ) ); |
| #else |
| ( pDosEntry->d_type & DOS_DIRECT ) ); |
| #endif |
| sal_Bool bIsFileAndWantsFile = |
| ( ( pDir->eAttrMask & FSYS_KIND_FILE ) && |
| #ifdef ICC |
| !( pDosEntry->d_type & ( strcmp(pDosEntry->d_name,".") || |
| strcmp(pDosEntry->d_name,"..")) ) && |
| #else |
| !( pDosEntry->d_type & DOS_DIRECT ) && |
| #endif |
| !( pDosEntry->d_type & DOS_VOLUMEID ) ); |
| sal_Bool bIsHidden = (pDosEntry->d_type & _A_HIDDEN) != 0; |
| sal_Bool bWantsHidden = 0 == ( pDir->eAttrMask & FSYS_KIND_VISIBLE ); |
| if ( ( bIsDirAndWantsDir || bIsFileAndWantsFile ) && |
| ( bWantsHidden || !bIsHidden ) && |
| pDir->aNameMask.Matches( String(aLowerName, osl_getThreadTextEncoding()) ) ) |
| { |
| #ifdef DBG_UTIL |
| DbgOutf( "%s %s flags:%x found", |
| pDosEntry->d_name, |
| bIsFileAndWantsFile ? "file" : "dir", |
| pDosEntry->d_type ); |
| #endif |
| DirEntryFlag eFlag = |
| 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT |
| : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT |
| : FSYS_FLAG_NORMAL; |
| DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name), |
| eFlag, FSYS_STYLE_NTFS ); |
| #ifdef FEAT_FSYS_DOUBLESPEED |
| pTemp->ImpSetStat( new FileStat( (void*) pDosDir, (void*) 0 ) ); |
| #endif |
| if ( pParent ) |
| pTemp->ImpChangeParent( new DirEntry( *pParent ), sal_False ); |
| if ( pDir->pStatLst ) //Status fuer Sort gewuenscht? |
| { |
| FileStat *pNewStat = new FileStat( (void*) pDosDir, (void*) 0 ); |
| pDir->ImpSortedInsert( pTemp, pNewStat ); |
| } |
| else |
| pDir->ImpSortedInsert( pTemp, NULL ); |
| return 1; |
| } |
| #ifdef DBG_UTIL |
| else |
| DbgOutf( "%s flags:%x skipped", |
| pDosEntry->d_name, |
| pDosEntry->d_type ); |
| #endif |
| |
| } |
| else |
| bReady = sal_True; |
| return 0; |
| } |
| |
| /************************************************************************* |
| |* |
| |* InitFileStat() |
| |* |
| |* Beschreibung gemeinsamer Teil der Ctoren fuer FileStat |
| |* Ersterstellung MI 28.08.92 |
| |* Letzte Aenderung MI 28.08.92 |
| |* |
| *************************************************************************/ |
| |
| void FileStat::ImpInit( void* p ) |
| { |
| _WIN32_FIND_DATAA *pDirEnt = (_WIN32_FIND_DATAA*) p; |
| |
| nError = FSYS_ERR_OK; |
| nSize = pDirEnt->nFileSizeLow; |
| |
| SYSTEMTIME aSysTime; |
| FILETIME aLocTime; |
| |
| // use the last write date / time when the creation date / time isn't set |
| if ( ( pDirEnt->ftCreationTime.dwLowDateTime == 0 ) && |
| ( pDirEnt->ftCreationTime.dwHighDateTime == 0 ) ) |
| { |
| pDirEnt->ftCreationTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime; |
| pDirEnt->ftCreationTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime; |
| } |
| |
| // use the last write date / time when the last accessed date / time isn't set |
| if ( ( pDirEnt->ftLastAccessTime.dwLowDateTime == 0 ) && |
| ( pDirEnt->ftLastAccessTime.dwHighDateTime == 0 ) ) |
| { |
| pDirEnt->ftLastAccessTime.dwLowDateTime = pDirEnt->ftLastWriteTime.dwLowDateTime; |
| pDirEnt->ftLastAccessTime.dwHighDateTime = pDirEnt->ftLastWriteTime.dwHighDateTime; |
| } |
| |
| FileTimeToLocalFileTime( &pDirEnt->ftCreationTime, &aLocTime ); |
| FileTimeToSystemTime( &aLocTime, &aSysTime ); |
| aDateCreated = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear ); |
| aTimeCreated = Time( aSysTime.wHour, aSysTime.wMinute, |
| aSysTime.wSecond, 0 ); |
| |
| FileTimeToLocalFileTime( &pDirEnt->ftLastWriteTime, &aLocTime ); |
| FileTimeToSystemTime( &aLocTime, &aSysTime ); |
| aDateModified = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear ); |
| aTimeModified = Time( aSysTime.wHour, aSysTime.wMinute, |
| aSysTime.wSecond, 0 ); |
| |
| FileTimeToLocalFileTime( &pDirEnt->ftLastAccessTime, &aLocTime ); |
| FileTimeToSystemTime( &aLocTime, &aSysTime ); |
| aDateAccessed = Date( aSysTime.wDay, aSysTime.wMonth, aSysTime.wYear ); |
| aTimeAccessed = Time( aSysTime.wHour, aSysTime.wMinute, |
| aSysTime.wSecond, 0 ); |
| |
| nKindFlags = FSYS_KIND_FILE; |
| if ( pDirEnt->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) |
| nKindFlags = FSYS_KIND_DIR; |
| } |
| |
| /************************************************************************* |
| |* |
| |* FileStat::FileStat() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 27.08.92 |
| |* Letzte Aenderung MI 28.08.92 |
| |* |
| *************************************************************************/ |
| |
| FileStat::FileStat( const void *pInfo, // struct dirent |
| const void * ): // dummy |
| aDateCreated(0), |
| aTimeCreated(0), |
| aDateModified(0), |
| aTimeModified(0), |
| aDateAccessed(0), |
| aTimeAccessed(0) |
| { |
| ImpInit( ( (dirent*) pInfo ) ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* FileStat::Update() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 27.08.92 |
| |* Letzte Aenderung MI 28.08.92 |
| |* |
| *************************************************************************/ |
| |
| #ifdef _MSC_VER |
| #pragma warning(push, 1) |
| #pragma warning(disable: 4917) |
| #endif |
| #include <shlobj.h> |
| #ifdef _MSC_VER |
| #pragma warning(pop) |
| #endif |
| |
| #ifdef UNICODE |
| #define lstrchr wcschr |
| #define lstrncmp wcsncmp |
| #else |
| #define lstrchr strchr |
| #define lstrncmp strncmp |
| #endif |
| |
| //--------------------------------------------------------------------------- |
| |
| void SHFreeMem( void *p ) |
| { |
| LPMALLOC pMalloc = NULL; |
| |
| if ( SUCCEEDED(SHGetMalloc(&pMalloc)) ) |
| { |
| pMalloc->Free( p ); |
| pMalloc->Release(); |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| HRESULT SHGetIDListFromPath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl ) |
| { |
| if ( IsBadWritePtr(ppidl, sizeof(LPITEMIDLIST)) ) |
| return E_INVALIDARG; |
| |
| LPSHELLFOLDER pDesktopFolder = NULL; |
| |
| HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder ); |
| if ( FAILED(hResult) ) |
| return hResult; |
| |
| ULONG chEaten = lstrlen( pszPath ); |
| DWORD dwAttributes = FILE_ATTRIBUTE_DIRECTORY; |
| |
| #ifdef UNICODE |
| LPOLESTR wszPath = pszPath; |
| #else |
| WCHAR wszPath[MAX_PATH]; |
| MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszPath, -1, wszPath, MAX_PATH ); |
| #endif |
| |
| hResult = pDesktopFolder->ParseDisplayName( hwndOwner, (LPBC)NULL, wszPath, &chEaten, ppidl, &dwAttributes ); |
| pDesktopFolder->Release(); |
| |
| return hResult; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| HRESULT SHGetFolderFromIDList( LPCITEMIDLIST pidl, LPSHELLFOLDER *ppFolder ) |
| { |
| if ( IsBadWritePtr(ppFolder, sizeof(LPSHELLFOLDER)) ) |
| return E_INVALIDARG; |
| |
| *ppFolder = NULL; |
| |
| LPSHELLFOLDER pDesktopFolder = NULL; |
| |
| HRESULT hResult = SHGetDesktopFolder( &pDesktopFolder ); |
| if ( FAILED(hResult) ) |
| return hResult; |
| |
| hResult = pDesktopFolder->BindToObject( pidl, (LPBC)NULL, IID_IShellFolder, (LPVOID *)ppFolder ); |
| pDesktopFolder->Release(); |
| |
| return hResult; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| HRESULT SHResolvePath( HWND hwndOwner, LPCTSTR pszPath, LPITEMIDLIST *ppidl ) |
| { |
| // If hwndOwner is NULL, use the desktop window, because dialogs need a parent |
| |
| #ifdef BOOTSTRAP |
| return NO_ERROR; |
| #else |
| if ( !hwndOwner ) |
| hwndOwner = GetDesktopWindow(); |
| |
| HRESULT hResult = NOERROR; |
| LPTSTR pszPathCopy; |
| LPTSTR pszTrailingPath; |
| TCHAR cBackup = 0; |
| |
| // First make a copy of the path |
| |
| pszPathCopy = new TCHAR[lstrlen(pszPath) + 1]; |
| if ( pszPathCopy ) |
| lstrcpy( pszPathCopy, pszPath ); |
| else |
| return E_OUTOFMEMORY; |
| |
| // Determine the first token |
| |
| if ( !lstrncmp( pszPathCopy, "\\\\", 2 ) ) |
| pszTrailingPath = lstrchr( pszPathCopy + 2, '\\' ); |
| else |
| pszTrailingPath = lstrchr( pszPathCopy, '\\' ); |
| |
| // Now scan the path tokens |
| |
| while ( SUCCEEDED(hResult) ) |
| { |
| if ( pszTrailingPath ) |
| { |
| cBackup = *(++pszTrailingPath); |
| *pszTrailingPath = 0; |
| } |
| |
| LPITEMIDLIST pidl = NULL; |
| |
| // Make item ID list from leading path |
| |
| hResult = SHGetIDListFromPath( hwndOwner, pszPathCopy, &pidl ); |
| |
| // if path exists try to open it as folder |
| |
| if ( SUCCEEDED(hResult) ) |
| { |
| // Only open the folder if it was not the last token |
| |
| if ( pszTrailingPath ) |
| { |
| LPSHELLFOLDER pFolder; |
| |
| // Create a folder instance |
| hResult = SHGetFolderFromIDList( pidl, &pFolder); |
| |
| // Is it a folder ? |
| if ( SUCCEEDED(hResult) ) |
| { |
| // No try to instantiate an enumerator. |
| // This should popup a login dialog if any |
| |
| LPENUMIDLIST pEnum = NULL; |
| |
| hResult = pFolder->EnumObjects( hwndOwner, |
| SHCONTF_NONFOLDERS | SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN, |
| &pEnum ); |
| |
| // Release the enumerator interface |
| if ( SUCCEEDED(hResult) ) |
| pEnum->Release(); |
| |
| // Release the folder interface |
| pFolder->Release(); |
| } |
| |
| SHFreeMem( pidl ); |
| } |
| else // It was the last token |
| { |
| if ( ppidl ) |
| *ppidl = pidl; |
| else |
| SHFreeMem( pidl ); |
| } |
| } |
| |
| |
| // Forward to next token |
| |
| if ( pszTrailingPath ) |
| { |
| *pszTrailingPath = cBackup; |
| pszTrailingPath = lstrchr( pszTrailingPath, '\\' ); |
| } |
| else |
| break; |
| } |
| |
| // Free the working copy of the path |
| delete pszPathCopy; |
| |
| // NOERROR or OLE error code |
| return hResult; |
| #endif |
| } |
| |
| //--------------------------------------------------------------------------- |
| // The Wrapper |
| //--------------------------------------------------------------------------- |
| |
| sal_Bool Exists_Impl( const ByteString & crPath ) |
| { |
| // We do not know if OLE was initialized for this thread |
| |
| CoInitialize( NULL ); |
| |
| sal_Bool bSuccess = SUCCEEDED( SHResolvePath(NULL, crPath.GetBuffer(), NULL) ); |
| |
| CoUninitialize(); |
| |
| return bSuccess; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| sal_Bool FileStat::Update( const DirEntry& rDirEntry, sal_Bool bForceAccess ) |
| { |
| nSize = 0; |
| nKindFlags = 0; |
| aCreator.Erase(); |
| aType.Erase(); |
| aDateCreated = Date(0); |
| aTimeCreated = Time(0); |
| aDateModified = Date(0); |
| aTimeModified = Time(0); |
| aDateAccessed = Date(0); |
| aTimeAccessed = Time(0); |
| |
| if ( !rDirEntry.IsValid() ) |
| { |
| nError = FSYS_ERR_UNKNOWN; |
| nKindFlags = 0; |
| return sal_False; |
| } |
| |
| // Sonderbehandlung falls es sich um eine Root ohne Laufwerk handelt |
| |
| if ( !rDirEntry.aName.Len() && rDirEntry.eFlag == FSYS_FLAG_ABSROOT ) |
| { |
| nKindFlags = FSYS_KIND_DIR; |
| nError = FSYS_ERR_OK; |
| return sal_True; |
| } |
| |
| // keine Error-Boxen anzeigen |
| FSysFailOnErrorImpl(); |
| |
| // Redirect |
| String aPath( rDirEntry.GetFull() ); |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect( aPath ); |
| #endif |
| DirEntry aDirEntry( aPath ); |
| |
| // ist ein Medium im Laufwerk? |
| HACK("wie?") |
| sal_Bool bAccess = sal_True; |
| const DirEntry *pTop = aDirEntry.ImpGetTopPtr(); |
| ByteString aName = ByteString(pTop->aName).ToLowerAscii(); |
| if ( !bForceAccess && |
| ( pTop->eFlag == FSYS_FLAG_ABSROOT || |
| pTop->eFlag == FSYS_FLAG_RELROOT || |
| pTop->eFlag == FSYS_FLAG_VOLUME ) ) |
| if ( aName == "a:" || aName == "b:" ) |
| bAccess = sal_False; |
| else |
| DBG_TRACE( "FSys: will access removable device!" ); |
| if ( bAccess && ( aName == "a:" || aName == "b:" ) ) { |
| DBG_WARNING( "floppy will clatter" ); |
| } |
| |
| // Sonderbehandlung, falls es sich um ein Volume handelt |
| if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME || |
| aDirEntry.eFlag == FSYS_FLAG_ABSROOT ) |
| { |
| if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ) |
| nKindFlags = FSYS_KIND_DEV | ( aDirEntry.aName.Len() == 2 |
| ? FSYS_KIND_BLOCK |
| : FSYS_KIND_CHAR ); |
| else |
| nKindFlags = FSYS_KIND_DIR; |
| |
| if ( !bAccess ) |
| { |
| if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ) |
| nKindFlags |= FSYS_KIND_REMOVEABLE; |
| nError = FSYS_ERR_NOTEXISTS; |
| nKindFlags = 0; |
| return sal_False; |
| } |
| |
| ByteString aRootDir = aDirEntry.aName; |
| aRootDir += ByteString( "\\" ); |
| UINT nType = GetDriveType( (char *) aRootDir.GetBuffer() ); //TPF: 2i |
| if ( nType == 1 || nType == 0 ) |
| { |
| nError = FSYS_ERR_NOTEXISTS; |
| nKindFlags = 0; |
| return sal_False; |
| } |
| |
| if ( aDirEntry.eFlag == FSYS_FLAG_VOLUME ) |
| nKindFlags = nKindFlags | |
| ( ( nType == DRIVE_REMOVABLE ) ? FSYS_KIND_REMOVEABLE : 0 ) | |
| ( ( nType == DRIVE_FIXED ) ? FSYS_KIND_FIXED : 0 ) | |
| ( ( nType == DRIVE_REMOTE ) ? FSYS_KIND_REMOTE : 0 ) | |
| ( ( nType == DRIVE_RAMDISK ) ? FSYS_KIND_RAM : 0 ) | |
| ( ( nType == DRIVE_CDROM ) ? FSYS_KIND_CDROM : 0 ) | |
| ( ( nType == 0 ) ? FSYS_KIND_UNKNOWN : 0 ); |
| |
| nError = ERRCODE_NONE; |
| |
| return sal_True; |
| } |
| |
| // Statusinformation vom Betriebssystem holen |
| HANDLE h; //() |
| _WIN32_FIND_DATAA aEntry = {}; |
| DirEntry aAbsEntry( aDirEntry ); |
| if ( bAccess && aAbsEntry.ToAbs() ) |
| { |
| // im Namen k"onnen auch ';*?' als normale Zeichen vorkommen |
| ByteString aFilePath( aAbsEntry.GetFull(), osl_getThreadTextEncoding() ); |
| |
| // MI: dann gehen Umlaute auf Novell-Servern nicht / wozu ueberhaupt |
| // CharUpperBuff( (char*) aFilePath.GetStr(), aFilePath.Len() ); |
| DBG_TRACE1( "FileStat: %s", aFilePath.GetBuffer() ); |
| h = aFilePath.Len() < 230 |
| // die Win32-API ist hier sehr schwammig |
| ? FindFirstFile( (char *) aFilePath.GetBuffer(), &aEntry )//TPF: 2i |
| : INVALID_HANDLE_VALUE; |
| |
| if ( INVALID_HANDLE_VALUE != h ) |
| { |
| if ( !( aEntry.dwFileAttributes & 0x40 ) ) // com1: etc. e.g. not encrypted (means normal) |
| { |
| ByteString aUpperName = Upper_Impl(ByteString(aAbsEntry.GetName(), osl_getThreadTextEncoding())); |
| |
| // HRO: #74051# Compare also with short alternate filename |
| if ( aUpperName != Upper_Impl( aEntry.cFileName ) && aUpperName != Upper_Impl( aEntry.cAlternateFileName ) ) |
| h = INVALID_HANDLE_VALUE; |
| } |
| } |
| |
| if ( INVALID_HANDLE_VALUE == h ) |
| { |
| DWORD dwError = GetLastError(); |
| |
| if ( ERROR_BAD_NET_NAME == dwError ) |
| { |
| nKindFlags = FSYS_KIND_UNKNOWN; |
| nError = FSYS_ERR_NOTEXISTS; |
| return sal_False; |
| } |
| |
| // UNC-Volume? |
| DirEntry *pTop = aAbsEntry.ImpGetTopPtr(); |
| if ( pTop->GetFlag() == FSYS_FLAG_ABSROOT && |
| ( pTop->aName.Len() > 1 && (pTop->aName.GetBuffer()[1] != ':' )) ) |
| { |
| if ( bForceAccess ) |
| { |
| if ( Exists_Impl( aFilePath ) ) |
| { |
| nKindFlags = FSYS_KIND_DIR|FSYS_KIND_REMOTE; |
| nError = FSYS_ERR_OK; |
| return sal_True; |
| } |
| else |
| { |
| nKindFlags = FSYS_KIND_UNKNOWN; |
| nError = FSYS_ERR_NOTEXISTS; |
| return sal_False; |
| } |
| } |
| } |
| } |
| } |
| else |
| h = INVALID_HANDLE_VALUE; |
| |
| if ( h == INVALID_HANDLE_VALUE ) |
| { |
| // Sonderbehandlung falls es sich um eine Wildcard handelt |
| ByteString aTempName( aDirEntry.GetName(), osl_getThreadTextEncoding() ); |
| if ( strchr( aTempName.GetBuffer(), '?' ) || |
| strchr( aTempName.GetBuffer(), '*' ) || |
| strchr( aTempName.GetBuffer(), ';' ) ) |
| { |
| nKindFlags = FSYS_KIND_WILD; |
| nError = FSYS_ERR_OK; |
| return sal_True; |
| } |
| |
| if ( bAccess ) |
| { |
| nError = FSYS_ERR_NOTEXISTS; |
| nKindFlags = FSYS_KIND_UNKNOWN; |
| } |
| else |
| nKindFlags = FSYS_KIND_REMOVEABLE; |
| } |
| else |
| { |
| ImpInit( &aEntry ); |
| FindClose( h ); |
| } |
| |
| if ( 0 != nError ) |
| nKindFlags = 0; |
| |
| return 0 == nError; |
| |
| } |
| |
| sal_Bool IsRedirectable_Impl( const ByteString &rPath ) |
| { |
| if ( rPath.Len() >= 3 && ':' == rPath.GetBuffer()[1] ) |
| { |
| ByteString aVolume = rPath.Copy( 0, 3 ); |
| UINT nType = GetDriveType( (char *) aVolume.GetBuffer() ); |
| SetLastError( ERROR_SUCCESS ); |
| return DRIVE_FIXED != nType; |
| } |
| return sal_False; |
| } |
| |
| /************************************************************************* |
| |* |
| |* TempDirImpl() |
| |* |
| |* Beschreibung liefert den Namens des Directories fuer temporaere |
| |* Dateien |
| |* Ersterstellung MI 16.03.94 |
| |* Letzte Aenderung MI 16.03.94 |
| |* |
| *************************************************************************/ |
| |
| const char* TempDirImpl( char *pBuf ) |
| { |
| if ( !GetTempPath( MAX_PATH, pBuf ) && |
| !GetWindowsDirectory( pBuf, MAX_PATH ) && |
| !GetEnvironmentVariable( "HOMEPATH", pBuf, MAX_PATH ) ) |
| return 0; |
| |
| return pBuf; |
| } |
| |
| //======================================================================= |
| |
| ErrCode FileStat::QueryDiskSpace( const String &rPath, |
| BigInt &rFreeBytes, BigInt &rTotalBytes ) |
| { |
| DWORD nSectorsPerCluster; /* address of sectors per cluster */ |
| DWORD nBytesPerSector; /* address of bytes per sector */ |
| DWORD nFreeClusters; /* address of number of free clusters */ |
| DWORD nClusters; /* address of total number of clusters */ |
| |
| ByteString aVol( DirEntry(rPath).ImpGetTopPtr()->GetName(), osl_getThreadTextEncoding()); |
| bool bOK = GetDiskFreeSpace( aVol.GetBuffer(), |
| &nSectorsPerCluster, &nBytesPerSector, |
| &nFreeClusters, &nClusters ); |
| if ( !bOK ) |
| return Sys2SolarError_Impl( GetLastError() ); |
| |
| BigInt aBytesPerCluster( BigInt(nSectorsPerCluster) * |
| BigInt(nBytesPerSector) ); |
| rFreeBytes = aBytesPerCluster * BigInt(nFreeClusters); |
| rTotalBytes = aBytesPerCluster * BigInt(nClusters); |
| return 0; |
| } |
| |
| //========================================================================= |
| |
| void FSysEnableSysErrorBox( sal_Bool bEnable ) |
| { // Preserve other Bits!! |
| sal_uInt32 nErrorMode = SetErrorMode( bEnable ? 0 : SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX ); |
| if ( bEnable ) |
| nErrorMode &= ~(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); |
| else |
| nErrorMode |= (SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); |
| SetErrorMode( nErrorMode ); |
| } |
| |
| |
| |