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