1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
17 //----------------------------------------------------------------------------
18 //------------------- Linux Sources of OSD_FileNode --------------------------
19 //----------------------------------------------------------------------------
21 #include <OSD_FileNode.hxx>
22 #include <OSD_OSDError.hxx>
23 #include <OSD_Path.hxx>
24 #include <OSD_Protection.hxx>
25 #include <OSD_WhoAmI.hxx>
26 #include <Quantity_Date.hxx>
27 #include <Standard_NullObject.hxx>
28 #include <Standard_ProgramError.hxx>
37 const OSD_WhoAmI Iam = OSD_WFileNode;
40 // Create a file/directory object
42 OSD_FileNode::OSD_FileNode ()
46 // Create and initialize a file/directory object
48 OSD_FileNode::OSD_FileNode (const OSD_Path& Name)
55 // Get values of object
57 void OSD_FileNode::Path (OSD_Path& Name)const{
64 // Set values of object
66 void OSD_FileNode::SetPath (const OSD_Path& Name){
74 // Test if specified file/directory exists
76 Standard_Boolean OSD_FileNode::Exists(){
80 // if (myPath.Name().Length()==0) A directory can have a null name field (ex: root)
81 // throw OSD_OSDError("OSD_FileNode::Exists : no name was given"); (LD)
83 // if (Failed()) Perror();
85 TCollection_AsciiString aBuffer;
86 myPath.SystemName ( aBuffer );
87 status = access ( aBuffer.ToCString() , F_OK );
89 if (status == 0) return (Standard_True);
90 else return ( Standard_False );
96 // Physically remove a file/directory
98 void OSD_FileNode::Remove(){
100 // if (myPath.Name().Length()==0) A directory can have a null name field (ex: root)
101 // throw OSD_OSDError("OSD_FileNode::Remove : no name was given"); (LD)
103 // if (Failed()) Perror();
105 TCollection_AsciiString aBuffer;
106 myPath.SystemName ( aBuffer );
108 if(access(aBuffer.ToCString(), W_OK))
110 myError.SetValue (errno, Iam, "Remove");
114 struct stat stat_buf;
116 if(stat(aBuffer.ToCString(), &stat_buf))
118 myError.SetValue (errno, Iam, "Remove");
122 if ( S_ISDIR(stat_buf.st_mode)) {
125 if(rmdir(aBuffer.ToCString()))
127 myError.SetValue (errno, Iam, "Remove");
133 else if ( S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode) ||
134 S_ISFIFO(stat_buf.st_mode) ) {
136 if (unlink ( aBuffer.ToCString()) == -1)
137 myError.SetValue (errno, Iam, "Remove");
140 myError.SetValue (EINVAL, Iam, "Remove");
147 // Move a file/directory to another path
149 void OSD_FileNode::Move(const OSD_Path& NewPath){
151 TCollection_AsciiString thisPath;
153 // if (myPath.Name().Length()==0)
154 // throw OSD_OSDError("OSD_FileNode::Move : no name was given");
156 // if (Failed()) Perror();
158 NewPath.SystemName( thisPath ); // Get internal path name
159 TCollection_AsciiString aBuffer;
160 myPath.SystemName ( aBuffer );
161 status = rename (aBuffer.ToCString(), thisPath.ToCString());
163 if (status == -1) myError.SetValue (errno, Iam, "Move");
166 // Copy a file to another path and name
167 int static copy_file( const char* src, const char* trg )
171 int fds = open( src, O_RDONLY );
175 int fdo = open( trg, O_WRONLY|O_TRUNC| O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
183 const int BUFSIZE=4096;
186 while ( ( n = read ( fds, buf, BUFSIZE )) >0 )
188 if ( write ( fdo, buf, n ) != n ) { // writing error
203 void OSD_FileNode::Copy(const OSD_Path& ToPath)
206 TCollection_AsciiString second_name;
208 // if (myPath.Name().Length()==0) Copy .login would raise !!
209 // throw OSD_OSDError("OSD_FileNode::Copy : no name was given");
210 // if (Failed()) Perror();
212 ToPath.SystemName (second_name);
214 TCollection_AsciiString aBuffer;
215 myPath.SystemName ( aBuffer );
216 status = copy_file(aBuffer.ToCString(), second_name.ToCString());
217 if (status != 0) myError.SetValue (-1, Iam, "Copy failed") ;// (LD)
219 printf("Status %d : errno # %d\n",status,errno);
227 // Get protections of a file/directory
229 OSD_Protection OSD_FileNode::Protection(){
230 OSD_Protection thisProt;
235 // if (myPath.Name().Length()==0)
236 // throw OSD_OSDError("OSD_FileNode::Protection : no name was given");
238 // if (Failed()) Perror();
240 TCollection_AsciiString aBuffer;
241 myPath.SystemName ( aBuffer );
242 status = stat(aBuffer.ToCString(), &myStat);
243 if (status == -1) myError.SetValue (errno, Iam, "Protection");
245 u = g = w = OSD_None;
247 if (myStat.st_mode & S_IRUSR) u |= OSD_R;
248 if (myStat.st_mode & S_IWUSR) u |= OSD_W;
249 if (myStat.st_mode & S_IXUSR) u |= OSD_X;
251 if (myStat.st_mode & S_IRGRP) g |= OSD_R;
252 if (myStat.st_mode & S_IWGRP) g |= OSD_W;
253 if (myStat.st_mode & S_IXGRP) g |= OSD_X;
255 if (myStat.st_mode & S_IROTH) w |= OSD_R;
256 if (myStat.st_mode & S_IWOTH) w |= OSD_W;
257 if (myStat.st_mode & S_IXOTH) w |= OSD_X;
260 thisProt.SetValues ((OSD_SingleProtection)s,
261 (OSD_SingleProtection)u,
262 (OSD_SingleProtection)g,
263 (OSD_SingleProtection)w);
269 // Set protections of a file/directory
271 void OSD_FileNode::SetProtection(const OSD_Protection& Prot){
274 // if (myPath.Name().Length()==0)
275 // throw OSD_OSDError("OSD_FileNode::SetProtection : no name was given");
277 // if (Failed()) Perror();
279 TCollection_AsciiString aBuffer;
280 myPath.SystemName ( aBuffer );
281 status = chmod (aBuffer.ToCString(), (mode_t)Prot.Internal() );
282 if (status == -1) myError.SetValue (errno, Iam, "SetProtection");
285 // return the date of last access of file/directory
287 Quantity_Date OSD_FileNode::CreationMoment(){
289 Quantity_Date result;
293 // if (myPath.Name().Length()==0)
294 // throw OSD_OSDError("OSD_FileNode::CreationMoment : no name was given");
296 // if (Failed()) Perror();
298 /* Get File Informations */
300 TCollection_AsciiString aBuffer;
301 myPath.SystemName ( aBuffer );
302 if (!stat ( aBuffer.ToCString(), &buffer )) {
303 time_t aTime = (time_t)buffer.st_ctime;
304 decode = localtime (&aTime);
305 result.SetValues (decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
306 decode->tm_hour, decode->tm_min, decode->tm_sec , 0,0);
309 result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
313 // return Last access of file/directory
315 Quantity_Date OSD_FileNode::AccessMoment(){
317 Quantity_Date result;
321 // if (myPath.Name().Length()==0)
322 // throw OSD_OSDError("OSD_FileNode::AccessMoment : no name was given");
324 // if (Failed()) Perror();
326 /* Get File Informations */
328 TCollection_AsciiString aBuffer;
329 myPath.SystemName ( aBuffer );
330 if (!stat ( aBuffer.ToCString(), &buffer )) {
331 time_t aTime = (time_t)buffer.st_ctime;
332 decode = localtime (&aTime);
333 result.SetValues (decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
334 decode->tm_hour, decode->tm_min, decode->tm_sec, 0,0 );
337 result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
342 void OSD_FileNode::Reset(){
346 Standard_Boolean OSD_FileNode::Failed()const{
347 return( myError.Failed());
350 void OSD_FileNode::Perror() {
355 Standard_Integer OSD_FileNode::Error()const{
356 return( myError.Error());
361 //----------------------------------------------------------------------------
362 //------------------- WNT Sources of OSD_FileNode ---------------------------
363 //----------------------------------------------------------------------------
370 #include <OSD_FileNode.hxx>
371 #include <OSD_Protection.hxx>
372 #include <Quantity_Date.hxx>
373 #include <Standard_ProgramError.hxx>
374 #include <TCollection_ExtendedString.hxx>
376 #include <OSD_WNT.hxx>
384 #define TEST_RAISE( arg ) _test_raise ( fName, ( arg ) )
385 #define RAISE( arg ) throw Standard_ProgramError ( ( arg ) )
388 // None of the existing security APIs are supported in a UWP applications
389 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, const wchar_t* );
390 BOOL __fastcall _osd_wnt_sd_to_protection (
391 PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL
394 Standard_Integer __fastcall _get_file_type ( Standard_CString, HANDLE );
396 void _osd_wnt_set_error ( OSD_Error&, Standard_Integer, ... );
398 static BOOL __fastcall _get_file_time (const wchar_t*, LPSYSTEMTIME, BOOL );
399 static void __fastcall _test_raise ( TCollection_AsciiString, Standard_CString );
401 //=======================================================================
402 //function : OSD_FileNode
403 //purpose : Empty Constructor
404 //=======================================================================
406 OSD_FileNode::OSD_FileNode ()
410 //=======================================================================
411 //function : OSD_FileNode
412 //purpose : Constructor
413 //=======================================================================
415 OSD_FileNode::OSD_FileNode ( const OSD_Path& Name )
418 } // end constructor ( 2 )
420 //=======================================================================
423 //=======================================================================
425 void OSD_FileNode::Path ( OSD_Path& Name ) const {
429 } // end OSD_FileNode :: Path
431 //=======================================================================
434 //=======================================================================
436 void OSD_FileNode::SetPath ( const OSD_Path& Name ) {
440 } // end OSD_FileNode :: SetPath
442 //=======================================================================
445 //=======================================================================
447 Standard_Boolean OSD_FileNode::Exists ()
451 Standard_Boolean retVal = Standard_False;
452 TCollection_AsciiString fName;
454 myPath.SystemName ( fName );
456 if ( fName.IsEmpty () ) return Standard_False;
457 TEST_RAISE( "Exists" );
459 // make wide character string from UTF-8
460 TCollection_ExtendedString fNameW(fName);
462 WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
464 if (!GetFileAttributesExW (fNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
466 if (GetLastError() != ERROR_FILE_NOT_FOUND)
468 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
473 retVal = Standard_True;
478 } // end OSD_FileNode :: Exists
480 //=======================================================================
483 //=======================================================================
485 void OSD_FileNode::Remove () {
487 TCollection_AsciiString fName;
489 myPath.SystemName ( fName );
490 TCollection_ExtendedString fNameW(fName);
492 TEST_RAISE( "Remove" );
494 switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
498 if (!DeleteFileW (fNameW.ToWideString()))
499 _osd_wnt_set_error ( myError, OSD_WFileNode, fNameW.ToWideString());
505 // LD : Suppression de l'appel a DeleteDirectory pour
506 // ne pas detruire un repertoire no vide.
508 if (!RemoveDirectoryW (fNameW.ToWideString()))
509 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
513 RAISE("OSD_FileNode :: Remove (): invalid file type - neither file nor directory");
516 } // end OSD_FileNode :: Remove
518 //=======================================================================
521 //=======================================================================
523 void OSD_FileNode::Move ( const OSD_Path& NewPath ) {
525 TCollection_AsciiString fName;
526 TCollection_AsciiString fNameDst;
528 myPath.SystemName ( fName );
529 TCollection_ExtendedString fNameW(fName);
531 TEST_RAISE( "Move" );
533 NewPath.SystemName ( fNameDst );
534 TCollection_ExtendedString fNameDstW(fNameDst);
536 switch (_get_file_type (fName.ToCString (), INVALID_HANDLE_VALUE)) {
540 if (!MoveFileExW (fNameW.ToWideString (),
541 fNameDstW.ToWideString (),
542 MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
543 _osd_wnt_set_error(myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
548 if (!MoveDirectory (fNameW.ToWideString(), fNameDstW.ToWideString()))
549 _osd_wnt_set_error(myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
553 RAISE("OSD_FileNode :: Move (): invalid file type - neither file nor directory");
556 } // end OSD_FileNode :: Move
558 //=======================================================================
561 //=======================================================================
563 void OSD_FileNode::Copy ( const OSD_Path& ToPath ) {
565 TCollection_AsciiString fName;
566 TCollection_AsciiString fNameDst;
568 myPath.SystemName ( fName );
569 TCollection_ExtendedString fNameW(fName);
571 TEST_RAISE( "Copy" );
573 ToPath.SystemName ( fNameDst );
574 TCollection_ExtendedString fNameDstW(fNameDst);
576 switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
580 if (!CopyFileW (fNameW.ToWideString(), fNameDstW.ToWideString(), FALSE))
582 if (CopyFile2 (fNameW.ToWideString(), fNameDstW.ToWideString(), FALSE) != S_OK)
584 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
589 if (!CopyDirectory (fNameW.ToWideString(), fNameDstW.ToWideString()))
590 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
595 RAISE("OSD_FileNode :: Copy (): invalid file type - neither file nor directory");
599 } // end OSD_FileNode :: Copy
601 // None of the existing security APIs are supported in a UWP applications
604 //=======================================================================
605 //function : Protection
607 //=======================================================================
609 OSD_Protection OSD_FileNode::Protection () {
611 OSD_Protection retVal;
612 TCollection_AsciiString fName;
613 PSECURITY_DESCRIPTOR pSD;
615 myPath.SystemName ( fName );
616 TCollection_ExtendedString fNameW(fName);
618 TEST_RAISE( "Protection" );
620 if ((pSD = GetFileSecurityEx (fNameW.ToWideString(), DACL_SECURITY_INFORMATION |OWNER_SECURITY_INFORMATION)) == NULL
621 || !_osd_wnt_sd_to_protection (
623 _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY)
626 _osd_wnt_set_error ( myError, OSD_WFileNode );
630 FreeFileSecurity ( pSD );
634 } // end OSD_FileNode :: Protection
636 //=======================================================================
637 //function : SetProtection
639 //=======================================================================
641 void OSD_FileNode::SetProtection ( const OSD_Protection& Prot ) {
643 TCollection_AsciiString fName;
644 PSECURITY_DESCRIPTOR pSD;
646 myPath.SystemName ( fName );
647 TCollection_ExtendedString fNameW(fName);
649 TEST_RAISE( "SetProtection" );
651 pSD = _osd_wnt_protection_to_sd (Prot,
652 _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY,
653 fNameW.ToWideString());
655 if (pSD == NULL || !SetFileSecurityW (fNameW.ToWideString(), DACL_SECURITY_INFORMATION, pSD))
656 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
662 } // end OSD_FileNode :: SetProtection
668 //=======================================================================
669 //function : Protection
671 //=======================================================================
673 OSD_Protection OSD_FileNode::Protection ()
675 TCollection_AsciiString fName;
677 myPath.SystemName ( fName );
678 TCollection_ExtendedString fNameW(fName);
680 OSD_SingleProtection aProt = OSD_None;
681 if (_waccess_s (fNameW.ToWideString(), 6))
683 else if (_waccess_s (fNameW.ToWideString(), 2))
685 else if (_waccess_s (fNameW.ToWideString(), 4))
688 // assume full access for system and none for everybody
689 OSD_Protection retVal (OSD_RWXD, aProt, aProt, OSD_None);
691 } // end OSD_FileNode :: Protection
693 //=======================================================================
694 //function : SetProtection
696 //=======================================================================
698 void OSD_FileNode::SetProtection ( const OSD_Protection& /*Prot*/ )
700 } // end OSD_FileNode :: SetProtection
704 //=======================================================================
705 //function : AccessMoment
707 //=======================================================================
709 Quantity_Date OSD_FileNode::AccessMoment () {
711 Quantity_Date retVal;
712 SYSTEMTIME stAccessMoment;
713 SYSTEMTIME stAccessSystemMoment;
714 TCollection_AsciiString fName;
716 myPath.SystemName ( fName );
717 TCollection_ExtendedString fNameW(fName);
719 TEST_RAISE( "AccessMoment" );
721 if (_get_file_time (fNameW.ToWideString(), &stAccessSystemMoment, TRUE))
723 SYSTEMTIME * aSysTime = &stAccessMoment;
724 BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL ,
725 &stAccessSystemMoment ,
727 if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
728 aSysTime = &stAccessSystemMoment;
729 retVal.SetValues (aSysTime->wMonth, aSysTime->wDay,
730 aSysTime->wYear, aSysTime->wHour,
731 aSysTime->wMinute, aSysTime->wSecond,
732 aSysTime->wMilliseconds
737 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
742 } // end OSD_FileNode :: AccessMoment
744 //=======================================================================
745 //function : CreationMoment
747 //=======================================================================
749 Quantity_Date OSD_FileNode::CreationMoment () {
751 Quantity_Date retVal;
752 SYSTEMTIME stCreationMoment;
753 SYSTEMTIME stCreationSystemMoment;
754 TCollection_AsciiString fName;
756 myPath.SystemName ( fName );
757 TCollection_ExtendedString fNameW(fName);
759 TEST_RAISE( "CreationMoment" );
761 if (_get_file_time (fNameW.ToWideString(), &stCreationSystemMoment, FALSE))
763 SYSTEMTIME * aSysTime = &stCreationMoment;
764 BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL,
765 &stCreationSystemMoment ,
767 if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
768 aSysTime = &stCreationSystemMoment;
769 retVal.SetValues (aSysTime->wMonth, aSysTime->wDay,
770 aSysTime->wYear, aSysTime->wHour,
771 aSysTime->wMinute, aSysTime->wSecond,
772 aSysTime->wMilliseconds
777 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
782 } // end OSD_FileNode :: CreationMoment
784 //=======================================================================
787 //=======================================================================
789 Standard_Boolean OSD_FileNode::Failed () const {
791 return myError.Failed ();
793 } // end OSD_FileNode :: Failed
795 //=======================================================================
798 //=======================================================================
800 void OSD_FileNode::Reset () {
804 } // end OSD_FileNode :: Reset
806 //=======================================================================
809 //=======================================================================
811 void OSD_FileNode::Perror () {
815 } // end OSD_FileNode :: Perror
817 //=======================================================================
820 //=======================================================================
822 Standard_Integer OSD_FileNode::Error () const {
824 return myError.Error ();
826 } // end OSD_FileNode :: Error
828 void _osd_wnt_set_error ( OSD_Error& err, Standard_Integer who, ... ) {
832 wchar_t buffer[2048];
836 va_start ( arg_ptr, who);
838 errCode = GetLastError ();
840 if ( !FormatMessageW (
841 FORMAT_MESSAGE_FROM_SYSTEM,
842 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
843 buffer, 2048, &arg_ptr
846 StringCchPrintfW(buffer, _countof(buffer), L"error code %d", (Standard_Integer)errCode);
848 SetLastError ( errCode );
853 WideCharToMultiByte(CP_UTF8, 0, buffer, -1, aBufferA, sizeof(aBufferA), NULL, NULL);
854 err.SetValue(errCode, who, aBufferA);
860 #if defined(__CYGWIN32__) || defined(__MINGW32__)
861 #ifdef __try /* is defined on MinGw as either "try" or "if (true)" */
866 #define __leave return retVal
869 static BOOL __fastcall _get_file_time (const wchar_t* fName, LPSYSTEMTIME lpSysTime, BOOL fAccess)
872 FILETIME ftCreationTime;
873 FILETIME ftLastWriteTime;
875 HANDLE hFile = INVALID_HANDLE_VALUE;
879 if ((hFile = CreateFileW (fName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)
880 ) == INVALID_HANDLE_VALUE
883 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams = {};
884 pCreateExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
885 pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
886 pCreateExParams.lpSecurityAttributes = NULL;
887 pCreateExParams.hTemplateFile = NULL;
888 if ((hFile = CreateFile2 (fName, NULL, NULL, OPEN_EXISTING, &pCreateExParams)) == INVALID_HANDLE_VALUE)
892 if ( !GetFileTime ( hFile, &ftCreationTime, NULL, &ftLastWriteTime ) ) __leave;
894 lpftPtr = fAccess ? &ftLastWriteTime : &ftCreationTime;
896 if ( !FileTimeToSystemTime ( lpftPtr, lpSysTime ) ) __leave;
904 if ( hFile != INVALID_HANDLE_VALUE )
906 CloseHandle ( hFile );
912 } // end _get_file_time
914 #if defined(__CYGWIN32__) || defined(__MINGW32__)
920 static void __fastcall _test_raise ( TCollection_AsciiString fName, Standard_CString str ) {
921 if ( fName.IsEmpty () ) {
922 TCollection_AsciiString buff = "OSD_FileNode :: ";
924 buff += " (): wrong access";
926 throw Standard_ProgramError(buff.ToCString());