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
Upper_Impl(const ByteString & rStr)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
opendir(const char * pPfad)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
readdir(DIR * pDir)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
closedir(DIR * pDir)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
GetPathStyle_Impl(const String & rDevice,FSysPathStyle & rStyle)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
GetPathStyle(const String & rDevice)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
IsCaseSensitive(FSysPathStyle eFormatter) const184 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
ToAbs()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
GetVolume() const311 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
SetCWD(sal_Bool bSloppy) const363 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
Init()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
Read()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
ImpInit(void * p)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
FileStat(const void * pInfo,const void *)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
SHFreeMem(void * p)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
SHGetIDListFromPath(HWND hwndOwner,LPCTSTR pszPath,LPITEMIDLIST * ppidl)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
SHGetFolderFromIDList(LPCITEMIDLIST pidl,LPSHELLFOLDER * ppFolder)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
SHResolvePath(HWND hwndOwner,LPCTSTR pszPath,LPITEMIDLIST * ppidl)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
Exists_Impl(const ByteString & crPath)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
Update(const DirEntry & rDirEntry,sal_Bool bForceAccess)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
IsRedirectable_Impl(const ByteString & rPath)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
TempDirImpl(char * pBuf)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
QueryDiskSpace(const String & rPath,BigInt & rFreeBytes,BigInt & rTotalBytes)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
FSysEnableSysErrorBox(sal_Bool bEnable)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