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.
15 //------------------------------------------------------------------------
17 //------------------------------------------------------------------------
22 #include <OSD_File.hxx>
23 #include <OSD_FromWhere.hxx>
24 #include <OSD_OSDError.hxx>
25 #include <OSD_Path.hxx>
26 #include <OSD_Protection.hxx>
27 #include <OSD_WhoAmI.hxx>
28 #include <Standard_PCharacter.hxx>
29 #include <Standard_ProgramError.hxx>
30 #include <TCollection_AsciiString.hxx>
32 const OSD_WhoAmI Iam = OSD_WFile;
34 #if defined (sun) || defined(SOLARIS)
47 #define NEWLINE '\10';
49 // ---------------------------------------------------------------------
50 // Create an empty file object
51 // ---------------------------------------------------------------------
53 OSD_File::OSD_File():OSD_FileNode()
55 ImperativeFlag = Standard_False;
58 myMode = OSD_ReadWrite;
59 myFILE = (Standard_Address) NULL;
64 // ---------------------------------------------------------------------
65 // Create and initialize a file object
66 // ---------------------------------------------------------------------
68 OSD_File::OSD_File(const OSD_Path& Name):OSD_FileNode(Name)
70 ImperativeFlag = Standard_False;
73 myMode = OSD_ReadWrite;
74 myFILE = (Standard_Address) NULL;
79 // protect against occasional use of myFileHande in Linux code
80 #define myFileHandle myFileHandle_is_only_for_Windows
82 // ---------------------------------------------------------------------
83 // Build a file if it doesn't exist or create again if it already exists
84 // ---------------------------------------------------------------------
86 void OSD_File::Build(const OSD_OpenMode Mode,
87 const OSD_Protection& Protect){
89 Standard_Integer internal_prot;
90 Standard_Integer internal_mode = O_CREAT | O_TRUNC ;
91 TCollection_AsciiString aBuffer;
93 if (myPath.Name().Length()==0)
94 throw Standard_ProgramError("OSD_File::Build : no name was given");
96 if (myFileChannel != -1)
97 throw Standard_ProgramError("OSD_File::Build : file is already open");
102 internal_prot = Protect.Internal();
104 const char* CMode = "r";
108 internal_mode |= O_RDONLY;
112 internal_mode |= O_WRONLY;
116 internal_mode |= O_RDWR;
121 myPath.SystemName( aBuffer );
122 myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
123 if (myFileChannel >= 0) {
124 myFILE = fdopen (myFileChannel, CMode);
127 /* Handle OPEN errors */
129 myError.SetValue (errno, Iam, "Open");
135 // ---------------------------------------------------------------------
136 // Append to an existing file
137 // ---------------------------------------------------------------------
139 void OSD_File::Append(const OSD_OpenMode Mode,
140 const OSD_Protection& Protect){
142 Standard_Integer internal_prot;
143 Standard_Integer internal_mode = O_APPEND;;
144 TCollection_AsciiString aBuffer;
146 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
147 throw Standard_ProgramError("OSD_File::Append : it is a directory");
150 if (myPath.Name().Length()==0)
151 throw Standard_ProgramError("OSD_File::Append : no name was given");
153 if (myFileChannel != -1)
154 throw Standard_ProgramError("OSD_File::Append : file is already open");
156 internal_prot = Protect.Internal();
158 const char* CMode = "r";
162 internal_mode |= O_RDONLY;
166 internal_mode |= O_WRONLY;
170 internal_mode |= O_RDWR;
175 // If file doesn't exist, creates it.
177 if (!Exists()) internal_mode |= O_CREAT;
179 myPath.SystemName ( aBuffer );
180 myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
181 if (myFileChannel >= 0)
182 myFILE = fdopen (myFileChannel, CMode);
184 /* Handle OPEN errors */
186 myError.SetValue (errno, Iam, "Open");
189 // ---------------------------------------------------------------------
191 // ---------------------------------------------------------------------
193 void OSD_File::Open(const OSD_OpenMode Mode,
194 const OSD_Protection& Protect){
196 Standard_Integer internal_prot;
197 Standard_Integer internal_mode = 0;
198 TCollection_AsciiString aBuffer;
200 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
201 myError.SetValue (1, Iam, "Could not be open : it is a directory");
204 if (myPath.Name().Length()==0)
205 throw Standard_ProgramError("OSD_File::Open : no name was given");
207 if (myFileChannel != -1)
208 throw Standard_ProgramError("OSD_File::Open : file is already open");
210 internal_prot = Protect.Internal();
212 const char* CMode = "r";
216 internal_mode |= O_RDONLY;
220 internal_mode |= O_WRONLY;
224 internal_mode |= O_RDWR;
229 myPath.SystemName ( aBuffer );
230 myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
231 if (myFileChannel >= 0)
232 myFILE = fdopen (myFileChannel, CMode);
234 /* Handle OPEN errors */
236 myError.SetValue (errno, Iam, "Open");
241 // ---------------------------------------------------------------------
242 // ---------------------------------------------------------------------
243 void OSD_File::BuildTemporary(){
248 #if defined(vax) || defined(__vms) || defined(VAXVMS)
253 dummy = open("dummy", O_RDWR | O_CREAT); // Open a dummy file
254 myFileChannel = dummy - 1; // This is file channel of "fic" +1
255 close(dummy); // Close dummy file
256 unlink("dummy"); // Removes dummy file
259 char name[] = "/tmp/CSFXXXXXX";
260 myFileChannel = mkstemp( name );
262 TCollection_AsciiString aName ( name ) ;
263 OSD_Path aPath( aName ) ;
267 myFILE = fdopen( myFileChannel, "w+" ) ;
271 myMode = OSD_ReadWrite;
276 // ---------------------------------------------------------------------
277 // Read content of a file
278 // ---------------------------------------------------------------------
280 void OSD_File::Read(TCollection_AsciiString& Buffer,
281 const Standard_Integer Nbyte){
282 Standard_PCharacter readbuf;
285 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
286 throw Standard_ProgramError("OSD_File::Read : it is a directory");
289 if (myFileChannel == -1)
290 throw Standard_ProgramError("OSD_File::Read : file is not open");
292 if (Failed()) Perror();
294 if (myMode == OSD_WriteOnly)
295 throw Standard_ProgramError("OSD_File::Read : file is Write only");
298 throw Standard_ProgramError("OSD_File::Read : Nbyte is null");
300 TCollection_AsciiString transfert(Nbyte,' ');
301 readbuf = (Standard_PCharacter)transfert.ToCString();
303 status = read (myFileChannel, readbuf, Nbyte);
305 Buffer = transfert; // Copy transfert to Buffer
307 if (status == -1) myError.SetValue (errno, Iam, "Read");
309 if ( status < Nbyte ) myIO = EOF;
313 // ---------------------------------------------------------------------
314 // Read a line from a file
315 // ---------------------------------------------------------------------
317 void OSD_File::ReadLine(TCollection_AsciiString& Buffer,
318 const Standard_Integer Nbyte,
319 Standard_Integer& NByteRead)
321 Standard_PCharacter readbuf, abuffer;
323 if (OSD_File::KindOfFile() == OSD_DIRECTORY ) {
324 throw Standard_ProgramError("OSD_File::Read : it is a directory");
326 if (myFileChannel == -1){
327 throw Standard_ProgramError("OSD_File::ReadLine : file is not open");
332 if (myMode == OSD_WriteOnly) {
333 throw Standard_ProgramError("OSD_File::ReadLine : file is Write only");
336 throw Standard_ProgramError("OSD_File::ReadLine : Nbyte is null");
339 TCollection_AsciiString transfert(Nbyte,' ');
340 readbuf = (Standard_PCharacter)transfert.ToCString();
342 abuffer = fgets(readbuf, Nbyte, (FILE *) myFILE);
344 if (abuffer == NULL) {
345 if (!feof((FILE *) myFILE)) {
346 myError.SetValue (errno, Iam, "ReadLine");
356 NByteRead = (Standard_Integer)strlen(abuffer);
357 Buffer.SetValue(1,abuffer); // Copy transfert to Buffer
358 Buffer.Trunc(NByteRead);
361 // --------------------------------------------------------------------------
362 // OSD::KindOfFile Retourne le type de fichier.
363 // --------------------------------------------------------------------------
364 OSD_KindFile OSD_File::KindOfFile ( ) const{
367 TCollection_AsciiString FullName;
371 aPath.SystemName (FullName);
372 status = stat (FullName.ToCString() , &buffer );
374 if ( S_ISDIR(buffer.st_mode) ) { return OSD_DIRECTORY ; }
375 else if ( S_ISREG(buffer.st_mode) ) { return OSD_FILE ; }
376 else if ( S_ISLNK(buffer.st_mode) ) { return OSD_LINK ; }
377 else if ( S_ISSOCK(buffer.st_mode) ) { return OSD_SOCKET ; }
378 else { return OSD_UNKNOWN ; }
383 // --------------------------------------------------------------------------
384 // Read content of a file
385 // --------------------------------------------------------------------------
386 void OSD_File::Read(const Standard_Address Buffer,
387 const Standard_Integer Nbyte,
388 Standard_Integer& Readbyte)
393 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
394 throw Standard_ProgramError("OSD_File::Read : it is a directory");
397 if (myFileChannel == -1)
398 throw Standard_ProgramError("OSD_File::Read : file is not open");
400 if (Failed()) Perror();
402 if (myMode == OSD_WriteOnly)
403 throw Standard_ProgramError("OSD_File::Read : file is Write only");
406 throw Standard_ProgramError("OSD_File::Read : Nbyte is null");
409 throw Standard_ProgramError("OSD_File::Read : Buffer is null");
411 status = read (myFileChannel, (char*) Buffer, Nbyte);
413 if (status == -1) myError.SetValue (errno, Iam, "Read");
415 if ( status < Nbyte ) myIO = EOF;
420 // Write content of a file
422 void OSD_File::Write(const TCollection_AsciiString &Buffer,
423 const Standard_Integer Nbyte){
425 Standard_CString writebuf;
428 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
429 throw Standard_ProgramError("OSD_File::Write : it is a directory");
432 if (myFileChannel == -1)
433 throw Standard_ProgramError("OSD_File::Write : file is not open");
435 if (Failed()) Perror();
437 if (myMode == OSD_ReadOnly)
438 throw Standard_ProgramError("OSD_File::Write : file is Read only");
441 throw Standard_ProgramError("OSD_File::Write : Nbyte is null");
443 writebuf = Buffer.ToCString();
445 status = write (myFileChannel, writebuf, Nbyte);
447 if ( status == -1) myError.SetValue (errno, Iam, "Write");
449 if ( status < Nbyte ) myIO = EOF;
453 void OSD_File::Write(const Standard_Address Buffer,
454 const Standard_Integer Nbyte)
459 if (myFileChannel == -1)
460 throw Standard_ProgramError("OSD_File::Write : file is not open");
462 if (Failed()) Perror();
464 if (myMode == OSD_ReadOnly)
465 throw Standard_ProgramError("OSD_File::Write : file is Read only");
468 throw Standard_ProgramError("OSD_File::Write : Nbyte is null");
470 status = write (myFileChannel, (const char *)Buffer, Nbyte);
472 if ( status == -1) myError.SetValue (errno, Iam, "Write");
474 if ( status < Nbyte ) myIO = EOF;
481 // Move file pointer to a specified position
483 void OSD_File::Seek(const Standard_Integer Offset,
484 const OSD_FromWhere Whence){
487 if (myFileChannel == -1)
488 throw Standard_ProgramError("OSD_File::Seek : file is not open");
490 if (Failed()) Perror();
493 case OSD_FromBeginning :
503 myError.SetValue (EINVAL, Iam, "Seek");
506 off_t status = lseek (myFileChannel, Offset, iwhere);
507 if (status == -1) myError.SetValue (errno, Iam, "Seek");
517 void OSD_File::Close(){
520 if (myFileChannel == -1)
521 throw Standard_ProgramError("OSD_File::Close : file is not open");
523 if (Failed()) Perror();
525 // note: it probably should be single call to fclose()...
526 status = close (myFileChannel);
528 if (status == -1) myError.SetValue (errno, Iam, "Close");
530 if ( myFILE != NULL ) {
531 status = fclose ( (FILE*) myFILE );
540 // --------------------------------------------------------------------------
541 // Test if at end of file
542 // --------------------------------------------------------------------------
544 Standard_Boolean OSD_File::IsAtEnd(){
545 if (myFileChannel == -1)
546 throw Standard_ProgramError("OSD_File::IsAtEnd : file is not open");
548 if (myIO == EOF) return (Standard_True);
549 return (Standard_False);
554 /*void OSD_File::Link(const TCollection_AsciiString& ToFile){
555 if (myFileChannel == -1)
556 throw Standard_ProgramError("OSD_File::Link : file is not open");
558 TCollection_AsciiString aBuffer;
559 myPath.SystemName ( aBuffer );
560 link ( aBuffer.ToCString(), ToFile.ToCString() );
566 void OSD_File::SetLock(const OSD_LockType Lock){
569 if (myFileChannel == -1)
570 throw Standard_ProgramError("OSD_File::SetLock : file is not open");
578 case OSD_ExclusiveLock :
579 case OSD_WriteLock : lock = F_LOCK;
581 case OSD_ReadLock : return;
583 default : myError.SetValue (EINVAL, Iam, "SetLock");
587 if (fstat (myFileChannel, &buf) == -1) {
588 myError.SetValue (errno, Iam, "SetLock");
592 status = lockf(myFileChannel, lock, buf.st_size);
593 if (status == -1) myError.SetValue (errno, Iam, "SetLock");
602 case OSD_ExclusiveLock :
603 case OSD_WriteLock : key.l_type = F_WRLCK;
605 case OSD_ReadLock : key.l_type = F_RDLCK;
607 case OSD_NoLock : return;
608 // default : myError.SetValue (EINVAL, Iam, "SetLock");
615 status = fcntl (myFileChannel, F_SETLKW, &key);
616 if (status == -1) myError.SetValue (errno, Iam, "SetLock");
619 if (Lock == OSD_ExclusiveLock){
620 fstat (myFileChannel, &buf);
621 TCollection_AsciiString aBuffer;
622 myPath.SystemName ( aBuffer );
623 chmod( aBuffer.ToCString() ,buf.st_mode | S_ISGID);
624 ImperativeFlag = Standard_True;
631 case OSD_ExclusiveLock :
632 case OSD_WriteLock : lock = F_WRLCK;
634 case OSD_ReadLock : lock = F_RDLCK;
636 default : myError.SetValue (EINVAL, Iam, "SetLock");
639 status = flock (myFileChannel, lock);
640 if (status == -1) myError.SetValue (errno, Iam, "SetLock");
649 // Remove a lock from a file
651 void OSD_File::UnLock(){
654 if (myFileChannel == -1)
655 throw Standard_ProgramError("OSD_File::UnLock : file is not open");
660 if (fstat(myFileChannel, &buf) == -1) {
661 myError.SetValue(errno, Iam, "UnsetLock");
665 status = lockf(myFileChannel,F_ULOCK, buf.st_size);
666 if (status == -1) myError.SetValue (errno, Iam, "SetLock");
674 fstat (myFileChannel, &buf);
675 TCollection_AsciiString aBuffer;
676 myPath.SystemName ( aBuffer );
677 chmod(aBuffer.ToCString(),buf.st_mode & ~S_ISGID);
678 ImperativeFlag = Standard_False;
680 key.l_type = F_UNLCK;
681 status = fcntl (myFileChannel, F_SETLK, &key);
682 if (status == -1) myError.SetValue (errno, Iam, "UnSetLock");
685 status = flock (myFileChannel, LOCK_UN);
686 if (status == -1) myError.SetValue (errno, Iam, "UnSetLock");
689 else myLock = OSD_NoLock;
696 // Return lock of a file
698 OSD_LockType OSD_File::GetLock(){
705 // --------------------------------------------------------------------------
706 // Return size of a file
707 // --------------------------------------------------------------------------
709 Standard_Size OSD_File::Size(){
713 if (myPath.Name().Length()==0)
714 throw Standard_ProgramError("OSD_File::Size : empty file name");
716 TCollection_AsciiString aBuffer;
717 myPath.SystemName ( aBuffer );
718 status = stat( aBuffer.ToCString() ,&buffer );
720 myError.SetValue (errno, Iam, "Size");
724 return (Standard_Size)buffer.st_size;
727 // --------------------------------------------------------------------------
728 // Test if a file is open
729 // --------------------------------------------------------------------------
731 Standard_Boolean OSD_File::IsOpen()const{
732 return (myFileChannel != -1);
736 Standard_Boolean OSD_File::IsLocked(){
737 return(myLock != OSD_NoLock);
740 Standard_Boolean OSD_File::IsReadable()
742 TCollection_AsciiString FileName ;
744 myPath.SystemName(FileName) ;
746 if (access(FileName.ToCString(),F_OK|R_OK))
747 return Standard_False;
749 return Standard_True;
752 Standard_Boolean OSD_File::IsWriteable()
754 TCollection_AsciiString FileName ;
756 myPath.SystemName(FileName) ;
758 if (access(FileName.ToCString(),F_OK|R_OK|W_OK))
759 return Standard_False;
761 return Standard_True;
764 Standard_Boolean OSD_File::IsExecutable()
766 TCollection_AsciiString FileName ;
768 myPath.SystemName(FileName) ;
770 if (access(FileName.ToCString(),F_OK|X_OK))
771 return Standard_False;
773 return Standard_True;
776 int OSD_File::Capture(int theDescr) {
777 // Duplicate an old file descriptor of the given one to be able to restore output to it later.
778 int oldDescr = dup(theDescr);
779 // Redirect the output to this file
780 dup2(myFileChannel, theDescr);
782 // Return the old descriptor
786 void OSD_File::Rewind() {
787 rewind((FILE*)myFILE);
792 //------------------------------------------------------------------------
793 //------------------- Windows NT sources for OSD_File -------------------
794 //------------------------------------------------------------------------
798 #include <OSD_File.hxx>
799 #include <OSD_Protection.hxx>
800 #include <Standard_ProgramError.hxx>
802 #include <OSD_WNT_1.hxx>
806 #include <Standard_PCharacter.hxx>
807 #include <TCollection_ExtendedString.hxx>
811 #if defined(__CYGWIN32__) || defined(__MINGW32__)
815 #define ACE_HEADER_SIZE ( sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) )
817 #define RAISE( arg ) throw Standard_ProgramError ( ( arg ) )
818 #define TEST_RAISE( arg ) _test_raise ( myFileHandle, ( arg ) )
822 #define OPEN_APPEND 2
824 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
826 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, const wchar_t* );
827 BOOL __fastcall _osd_wnt_sd_to_protection (
828 PSECURITY_DESCRIPTOR, OSD_Protection&, BOOL
830 static int __fastcall _get_buffer(HANDLE, Standard_PCharacter&, DWORD, BOOL, BOOL);
832 static void __fastcall _test_raise ( HANDLE, Standard_CString );
833 static Standard_Integer __fastcall _get_line (Standard_PCharacter& buffer, DWORD dwBuffSize, LONG& theSeekPos);
834 static DWORD __fastcall _get_access_mask ( OSD_SingleProtection );
835 static DWORD __fastcall _get_dir_access_mask ( OSD_SingleProtection prt );
836 static HANDLE __fastcall _open_file ( Standard_CString, OSD_OpenMode, DWORD, LPBOOL = NULL );
838 static OSD_SingleProtection __fastcall _get_protection ( DWORD );
839 static OSD_SingleProtection __fastcall _get_protection_dir ( DWORD );
841 typedef OSD_SingleProtection ( __fastcall *GET_PROT_FUNC ) ( DWORD );
843 Standard_Integer __fastcall _get_file_type ( Standard_CString, HANDLE );
845 // ---------------------------------------------------------------------
846 // Create an empty file object
847 // ---------------------------------------------------------------------
849 OSD_File :: OSD_File ()
851 ImperativeFlag = Standard_False;
855 myFileHandle = INVALID_HANDLE_VALUE;
856 } // end constructor ( 1 )
858 // ---------------------------------------------------------------------
859 // Create and initialize a file object
860 // ---------------------------------------------------------------------
862 OSD_File :: OSD_File ( const OSD_Path& Name ) : OSD_FileNode ( Name )
864 ImperativeFlag = Standard_False;
869 myFileHandle = INVALID_HANDLE_VALUE;
870 } // end constructor ( 2 )
872 // ---------------------------------------------------------------------
873 // Redirect a standard handle (fileno(stdout), fileno(stdin) or
874 // fileno(stderr) to this OSD_File and return the copy of the original
878 // aTmp.BuildTemporary();
879 // int stdfd = _fileno(stdout);
881 // int oldout = aTmp.Capture(stdfd);
882 // cout << "Some output to the file" << endl;
886 // _dup2(oldout, stdfd); // Restore standard output
888 // ---------------------------------------------------------------------
889 int OSD_File::Capture(int theDescr) {
890 // Get POSIX file descriptor from this file handle
891 int dFile = _open_osfhandle(reinterpret_cast<intptr_t>(myFileHandle), myMode);
895 _osd_wnt_set_error ( myError, OSD_WFile, myFileHandle );
899 // Duplicate an old file descriptor of the given one to be able to restore output to it later.
900 int oldDescr = _dup(theDescr);
901 // Redirect the output to this file
902 _dup2(dFile, theDescr);
904 // Return the old descriptor
908 void OSD_File::Rewind() {
909 LARGE_INTEGER aDistanceToMove;
910 aDistanceToMove.QuadPart = 0;
911 SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_BEGIN);
914 // protect against occasional use of myFileHande in Windows code
915 #define myFileChannel myFileChannel_is_only_for_Linux
917 // ---------------------------------------------------------------------
918 // Build a file if it doesn't exist or create again if it already exists
919 // ---------------------------------------------------------------------
921 void OSD_File :: Build ( const OSD_OpenMode Mode, const OSD_Protection& Protect) {
923 TCollection_AsciiString fName;
925 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
926 throw Standard_ProgramError("OSD_File::Read : it is a directory");
929 if (myFileHandle != INVALID_HANDLE_VALUE)
931 RAISE( "OSD_File :: Build (): incorrect call - file already opened" );
934 myPath.SystemName ( fName );
936 if ( fName.IsEmpty () )
938 RAISE( "OSD_File :: Build (): incorrent call - no filename given" );
940 myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_NEW );
942 if (myFileHandle == INVALID_HANDLE_VALUE)
944 _osd_wnt_set_error ( myError, OSD_WFile );
948 SetProtection ( Protect );
956 } // end OSD_File :: Build
960 // ---------------------------------------------------------------------
962 // ---------------------------------------------------------------------
964 void OSD_File :: Open (const OSD_OpenMode Mode, const OSD_Protection& /*Protect*/)
967 TCollection_AsciiString fName;
970 if (myFileHandle != INVALID_HANDLE_VALUE)
972 RAISE( "OSD_File :: Open (): incorrect call - file already opened" );
975 myPath.SystemName ( fName );
977 if ( fName.IsEmpty () )
979 RAISE( "OSD_File :: Open (): incorrent call - no filename given" );
981 myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_OLD );
983 if (myFileHandle == INVALID_HANDLE_VALUE) {
985 _osd_wnt_set_error ( myError, OSD_WFile );
989 myIO |= _get_file_type ( fName.ToCString (), myFileHandle );
991 } // end OSD_File :: Open
993 // ---------------------------------------------------------------------
994 // Append to an existing file
995 // ---------------------------------------------------------------------
997 void OSD_File :: Append ( const OSD_OpenMode Mode, const OSD_Protection& Protect) {
1000 TCollection_AsciiString fName;
1002 if (myFileHandle != INVALID_HANDLE_VALUE)
1004 RAISE( "OSD_File :: Append (): incorrect call - file already opened" );
1007 myPath.SystemName ( fName );
1009 if ( fName.IsEmpty () )
1011 RAISE( "OSD_File :: Append (): incorrent call - no filename given" );
1013 myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_APPEND, &fNew );
1015 if (myFileHandle == INVALID_HANDLE_VALUE)
1017 _osd_wnt_set_error ( myError, OSD_WFile );
1023 myIO |= _get_file_type ( fName.ToCString (), myFileHandle );
1024 Seek ( 0, OSD_FromEnd );
1028 SetProtection ( Protect );
1038 } // end OSD_File :: Append
1040 // ---------------------------------------------------------------------
1041 // Read content of a file
1042 // ---------------------------------------------------------------------
1044 void OSD_File :: Read (
1045 TCollection_AsciiString& Buffer, const Standard_Integer Nbyte
1048 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
1050 cout << " OSD_File::Read : it is a directory " << endl;
1053 // throw Standard_ProgramError("OSD_File::Read : it is a directory");
1056 Standard_Integer NbyteRead;
1058 TEST_RAISE( "Read" );
1060 char* buff = new Standard_Character[ Nbyte + 1 ];
1062 Read ( buff, Nbyte, NbyteRead );
1064 buff[ NbyteRead ] = 0;
1066 if ( NbyteRead != 0 )
1076 } // end OSD_File :: Read
1078 // ---------------------------------------------------------------------
1079 // Read a line from a file
1080 // ---------------------------------------------------------------------
1082 // Modified so that we have <nl> at end of line if we have read <nl> or <cr>
1084 // by LD 17 dec 98 for B4.4
1086 void OSD_File :: ReadLine (
1087 TCollection_AsciiString& Buffer,
1088 const Standard_Integer NByte, Standard_Integer& NbyteRead
1093 Standard_Character peekChar;
1094 Standard_PCharacter ppeekChar;
1095 Standard_PCharacter cBuffer;
1098 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
1099 throw Standard_ProgramError("OSD_File::Read : it is a directory");
1102 TEST_RAISE( "ReadLine" );
1104 if ( myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE ) )
1106 RAISE( "OSD_File :: ReadLine (): attempt to read from write only pipe" );
1108 // +----> leave space for end-of-string
1109 // | plus <CR><LF> sequence
1112 ppeekChar=&peekChar;
1113 cBuffer = new Standard_Character[ NByte + 3 ];
1115 if ( myIO & FLAG_FILE ) {
1117 if (!ReadFile (myFileHandle, cBuffer, NByte, &dwBytesRead, NULL)) { // an error occured
1119 _osd_wnt_set_error ( myError, OSD_WFile );
1123 } else if ( dwBytesRead == 0 ) { // end-of-file reached
1130 myIO &= ~FLAG_EOF ; // if the file increased since last read (LD)
1131 NbyteRead = _get_line (cBuffer, dwBytesRead, aSeekPos);
1133 if ( NbyteRead == -1 ) // last character in the buffer is <CR> -
1134 { // peek next character to see if it is a <LF>
1135 if (!ReadFile (myFileHandle, ppeekChar, 1, &dwDummy, NULL)) {
1137 _osd_wnt_set_error ( myError, OSD_WFile );
1139 } else if ( dwDummy != 0 ) { // end-of-file reached ?
1141 if (peekChar != '\n') // if we did not get a <CR><LF> sequence
1143 // adjust file position
1144 LARGE_INTEGER aDistanceToMove;
1145 aDistanceToMove.QuadPart = -1;
1146 SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
1151 NbyteRead = dwBytesRead;
1153 } else if ( aSeekPos != 0 )
1155 LARGE_INTEGER aDistanceToMove;
1156 aDistanceToMove.QuadPart = aSeekPos;
1157 SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
1162 } else if ( myIO & FLAG_SOCKET || myIO & FLAG_PIPE || myIO & FLAG_NAMED_PIPE ) {
1164 dwBytesRead = (DWORD)_get_buffer (myFileHandle, cBuffer,
1165 (DWORD)NByte, TRUE, myIO & FLAG_SOCKET);
1167 if ( ( int )dwBytesRead == -1 ) { // an error occured
1169 _osd_wnt_set_error ( myError, OSD_WFile );
1173 } else if ( dwBytesRead == 0 ) { // connection closed - set end-of-file flag
1181 NbyteRead = _get_line (cBuffer, dwBytesRead, aSeekPos);
1183 if (NbyteRead == -1) // last character in the buffer is <CR> -
1184 { // peek next character to see if it is a <LF>
1185 NbyteRead = dwBytesRead; // (LD) always fits this case.
1187 dwDummy = _get_buffer (myFileHandle, ppeekChar, 1, TRUE, myIO & FLAG_SOCKET);
1188 if ( ( int )dwDummy == -1 ) { // an error occured
1190 _osd_wnt_set_error ( myError, OSD_WFile );
1192 } else if ( dwDummy != 0 ) { // connection closed ?
1194 if ( peekChar == '\n' ) // we got a <CR><LF> sequence
1196 dwBytesRead++ ; // (LD) we have to jump <LF>
1201 } else if (aSeekPos != 0)
1203 dwBytesRead = dwBytesRead + aSeekPos;
1206 // Don't rewrite datas in cBuffer.
1208 Standard_PCharacter cDummyBuffer = new Standard_Character[ NByte + 3 ];
1210 // remove pending input
1211 _get_buffer (myFileHandle, cDummyBuffer, dwBytesRead, FALSE, myIO & FLAG_SOCKET);
1212 delete [] cDummyBuffer ;
1218 RAISE( "OSD_File :: ReadLine (): incorrect call - file is a directory" );
1220 if ( !Failed () && !IsAtEnd () )
1224 delete [] (Standard_PCharacter)cBuffer;
1226 } // end OSD_File :: ReadLine
1228 // --------------------------------------------------------------------------
1229 // Read content of a file
1230 // --------------------------------------------------------------------------
1232 void OSD_File :: Read (
1233 const Standard_Address Buffer,
1234 const Standard_Integer Nbyte, Standard_Integer& Readbyte
1239 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
1240 throw Standard_ProgramError("OSD_File::Read : it is a directory");
1243 TEST_RAISE( "Read" );
1245 if ( myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE ) )
1247 RAISE( "OSD_File :: Read (): attempt to read from write only pipe" );
1249 if (!ReadFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesRead, NULL)) {
1251 _osd_wnt_set_error ( myError, OSD_WFile );
1254 } else if ( dwBytesRead == 0 )
1262 Readbyte = ( Standard_Integer )dwBytesRead;
1264 } // end OSD_File :: Read
1266 void OSD_File :: Write (
1267 const TCollection_AsciiString& Buffer,
1268 const Standard_Integer Nbyte
1271 Write ( ( Standard_Address )Buffer.ToCString (), Nbyte );
1273 } // end OSD_File :: Write
1275 // --------------------------------------------------------------------------
1276 // Write content of a file
1277 // --------------------------------------------------------------------------
1279 void OSD_File :: Write (
1280 const Standard_Address Buffer,
1281 const Standard_Integer Nbyte
1284 DWORD dwBytesWritten;
1286 TEST_RAISE( "Write" );
1288 if ( myIO & FLAG_PIPE && myIO & FLAG_READ_PIPE )
1290 RAISE( "OSD_File :: Write (): attempt to write to read only pipe" );
1292 if (!WriteFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesWritten, NULL) ||
1293 dwBytesWritten != (DWORD)Nbyte)
1295 _osd_wnt_set_error ( myError, OSD_WFile );
1297 } // end OSD_File :: Write
1299 void OSD_File :: Seek (
1300 const Standard_Integer Offset, const OSD_FromWhere Whence
1303 DWORD dwMoveMethod = 0;
1305 TEST_RAISE( "Seek" );
1307 if ( myIO & FLAG_FILE || myIO & FLAG_DIRECTORY ) {
1311 case OSD_FromBeginning:
1313 dwMoveMethod = FILE_BEGIN;
1319 dwMoveMethod = FILE_CURRENT;
1325 dwMoveMethod = FILE_END;
1331 RAISE( "OSD_File :: Seek (): invalid parameter" );
1334 LARGE_INTEGER aDistanceToMove, aNewFilePointer;
1335 aNewFilePointer.QuadPart = 0;
1336 aDistanceToMove.QuadPart = Offset;
1338 if (!SetFilePointerEx(myFileHandle, aDistanceToMove, &aNewFilePointer, dwMoveMethod))
1340 _osd_wnt_set_error ( myError, OSD_WFile );
1346 } // end OSD_File :: Seek
1348 // --------------------------------------------------------------------------
1350 // --------------------------------------------------------------------------
1352 void OSD_File :: Close () {
1354 TEST_RAISE( "Close" );
1356 CloseHandle (myFileHandle);
1358 myFileHandle = INVALID_HANDLE_VALUE;
1361 } // end OSD_File :: Close
1363 // --------------------------------------------------------------------------
1364 // Test if at end of file
1365 // --------------------------------------------------------------------------
1367 Standard_Boolean OSD_File :: IsAtEnd () {
1369 TEST_RAISE( "IsAtEnd" );
1371 if (myIO & FLAG_EOF)
1372 return Standard_True ;
1373 return Standard_False ;
1375 } // end OSD_File :: IsAtEnd
1377 OSD_KindFile OSD_File :: KindOfFile () const {
1379 OSD_KindFile retVal;
1380 Standard_Integer flags;
1382 if (myFileHandle == INVALID_HANDLE_VALUE) {
1384 TCollection_AsciiString fName;
1386 myPath.SystemName ( fName );
1388 if ( fName.IsEmpty () )
1390 RAISE( "OSD_File :: KindOfFile (): incorrent call - no filename given" );
1392 flags = _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE);
1398 switch ( flags & FLAG_TYPE ) {
1406 case FLAG_DIRECTORY:
1408 retVal = OSD_DIRECTORY;
1414 retVal = OSD_SOCKET;
1420 retVal = OSD_UNKNOWN;
1426 } // end OSD_File :: KindOfFile
1428 //-------------------------------------------------debutpri???980424
1430 typedef struct _osd_wnt_key {
1438 void OSD_File::BuildTemporary () {
1441 wchar_t tmpPath[ MAX_PATH ];
1444 // Windows Registry not supported by UWP
1448 OSD_WNT_KEY regKey[ 2 ] = {
1450 { HKEY_LOCAL_MACHINE,
1451 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
1454 L".DEFAULT\\Environment"
1459 for ( int i = 0; i < 2; ++i ) {
1461 if ( RegOpenKeyExW (
1462 regKey[ i ].hKey, regKey[ i ].keyPath, 0, KEY_QUERY_VALUE, &hKey
1469 if ( RegQueryValueExW (
1470 hKey, L"TEMP", NULL, &dwType, NULL, &dwSize
1474 wchar_t* kVal = (wchar_t*)HeapAlloc (
1475 GetProcessHeap (), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
1476 dwSize + sizeof (wchar_t)
1479 RegQueryValueExW ( hKey, L"TEMP", NULL, &dwType, ( LPBYTE )kVal, &dwSize );
1481 if ( dwType == REG_EXPAND_SZ )
1483 ExpandEnvironmentStringsW ( kVal, tmpPath, MAX_PATH );
1487 StringCchCopyW (tmpPath, _countof(tmpPath), kVal);
1489 HeapFree ( GetProcessHeap (), 0, ( LPVOID )kVal );
1494 RegCloseKey ( hKey );
1502 if (GetTempPathW(_countof(tmpPath), tmpPath))
1505 if ( !fOK ) StringCchCopyW(tmpPath, _countof(tmpPath), L"./");
1507 GetTempFileNameW ( tmpPath, L"CSF", 0, tmpPath );
1512 char tmpPathA[MAX_PATH];
1513 WideCharToMultiByte(CP_UTF8, 0, tmpPath, -1, tmpPathA, sizeof(tmpPathA), NULL, NULL);
1514 SetPath(OSD_Path(tmpPathA));
1516 Build ( OSD_ReadWrite, prt );
1517 } // end OSD_File :: BuildTemporary
1519 //-------------------------------------------------finpri???980424
1521 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1524 #define __leave return
1527 void OSD_File :: SetLock ( const OSD_LockType Lock ) {
1532 TEST_RAISE( "SetLock" );
1534 ZeroMemory ( &ovlp, sizeof ( OVERLAPPED ) );
1538 if ( ( myLock = Lock ) == OSD_NoLock ) {
1543 } else if ( myLock == OSD_ReadLock || myLock == OSD_ExclusiveLock ) {
1545 dwFlags = LOCKFILE_EXCLUSIVE_LOCK;
1551 LARGE_INTEGER aSize;
1552 aSize.QuadPart = Size();
1553 if (!LockFileEx (myFileHandle, dwFlags, 0, aSize.LowPart, aSize.HighPart, &ovlp)) {
1555 _osd_wnt_set_error ( myError, OSD_WFile );
1560 ImperativeFlag = Standard_True;
1567 leave: ; // added for VisualAge
1569 } // end OSD_File :: SetLock
1571 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1577 void OSD_File :: UnLock () {
1579 TEST_RAISE( "Unlock" );
1581 if ( ImperativeFlag ) {
1583 LARGE_INTEGER aSize;
1584 aSize.QuadPart = Size();
1586 OVERLAPPED anOverlappedArea;
1587 anOverlappedArea.Offset = 0;
1588 anOverlappedArea.OffsetHigh = 0;
1590 if (!UnlockFileEx(myFileHandle, 0, aSize.LowPart, aSize.HighPart,&anOverlappedArea))
1591 _osd_wnt_set_error ( myError, OSD_WFile );
1593 ImperativeFlag = Standard_False;
1597 } // end OSD_File :: UnLock
1599 OSD_LockType OSD_File :: GetLock () {
1603 } // end OSD_File :: GetLock
1605 Standard_Boolean OSD_File :: IsLocked () {
1607 TEST_RAISE( "IsLocked" );
1609 return ImperativeFlag;
1611 } // end OSD_File :: IsLocked
1614 // --------------------------------------------------------------------------
1615 // Return size of a file
1616 // --------------------------------------------------------------------------
1618 Standard_Size OSD_File::Size()
1621 #if (_WIN32_WINNT >= 0x0500)
1622 LARGE_INTEGER aSize;
1624 if (GetFileSizeEx (myFileHandle, &aSize) == 0)
1626 _osd_wnt_set_error (myError, OSD_WFile);
1628 return (Standard_Size)aSize.QuadPart;
1630 DWORD aSize = GetFileSize (myFileHandle, NULL);
1631 if (aSize == INVALID_FILE_SIZE)
1633 _osd_wnt_set_error (myError, OSD_WFile);
1639 // --------------------------------------------------------------------------
1640 // Test if a file is open
1641 // --------------------------------------------------------------------------
1643 Standard_Boolean OSD_File :: IsOpen () const {
1645 return myFileHandle != INVALID_HANDLE_VALUE;
1647 } // end OSD_File :: IsOpen
1649 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1652 #define __leave return retVal
1656 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd (
1657 const OSD_Protection& prot, BOOL fDir, const wchar_t* fName
1663 HANDLE hProcess = NULL;
1668 DWORD dwAccessAdmin;
1669 DWORD dwAccessGroup;
1670 DWORD dwAccessOwner;
1671 DWORD dwAccessWorld;
1672 DWORD dwAccessAdminDir;
1673 // DWORD dwAccessGroupDir;
1674 DWORD dwAccessOwnerDir;
1675 // DWORD dwAccessWorldDir;
1676 DWORD dwACLsize = sizeof ( ACL );
1678 PTOKEN_OWNER pTkOwner = NULL;
1679 PTOKEN_GROUPS pTkGroups = NULL;
1680 PTOKEN_PRIMARY_GROUP pTkPrimaryGroup = NULL;
1681 PSECURITY_DESCRIPTOR retVal = NULL;
1682 PSECURITY_DESCRIPTOR pfSD = NULL;
1690 if ( !OpenProcessToken (
1691 GetCurrentProcess (), TOKEN_QUERY, &hProcess
1695 if ( ( pTkGroups = ( PTOKEN_GROUPS )GetTokenInformationEx (
1696 hProcess, TokenGroups
1701 if ( ( pTkOwner = ( PTOKEN_OWNER )GetTokenInformationEx (
1702 hProcess, TokenOwner
1707 if ( ( pTkPrimaryGroup = ( PTOKEN_PRIMARY_GROUP )GetTokenInformationEx (
1708 hProcess, TokenPrimaryGroup
1715 if ( fName == NULL )
1717 pSIDowner = pTkOwner -> Owner;
1721 pfSD = GetFileSecurityEx ( fName, OWNER_SECURITY_INFORMATION );
1723 if ( pfSD == NULL || !GetSecurityDescriptorOwner ( pfSD, &pSIDowner, &fDummy ) ) {
1732 pSIDadmin = AdminSid ();
1733 pSIDworld = WorldSid ();
1735 dwAccessAdmin = _get_access_mask ( prot.System () );
1736 dwAccessGroup = _get_access_mask ( prot.Group () );
1737 dwAccessOwner = _get_access_mask ( prot.User () );
1738 dwAccessWorld = _get_access_mask ( prot.World () );
1740 dwAccessAdminDir = _get_dir_access_mask ( prot.System () );
1741 // dwAccessGroupDir = _get_dir_access_mask ( prot.Group () );
1742 dwAccessOwnerDir = _get_dir_access_mask ( prot.User () );
1743 // dwAccessWorldDir = _get_dir_access_mask ( prot.World () );
1745 if ( dwAccessGroup != 0 ) {
1747 for ( i = 0; i < ( int )pTkGroups -> GroupCount; ++i ) {
1749 pSIDtemp = pTkGroups -> Groups[ i ].Sid;
1751 if ( !NtPredefinedSid ( pSIDtemp ) &&
1752 !EqualSid ( pSIDtemp, pSIDworld ) &&
1753 !EqualSid ( pSIDtemp, pTkPrimaryGroup -> PrimaryGroup ) &&
1754 IsValidSid ( pSIDtemp )
1757 dwACLsize += ( ( GetLengthSid ( pSIDtemp ) + ACE_HEADER_SIZE ) << j );
1763 dwACLsize += ( ( ( GetLengthSid ( pSIDowner ) + ACE_HEADER_SIZE ) << j ) +
1764 ( ( GetLengthSid ( pSIDadmin ) + ACE_HEADER_SIZE ) << j ) +
1765 ( ( GetLengthSid ( pSIDworld ) + ACE_HEADER_SIZE ) << j )
1768 if ( ( pACL = CreateAcl ( dwACLsize ) ) == NULL ) __leave;
1770 if ( dwAccessAdmin != 0 )
1772 if ( ( pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1779 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1783 pFileACE -> dwMask = dwAccessAdminDir;
1784 pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1785 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1789 FreeAce ( pFileACE );
1793 if ( dwAccessOwner != 0 )
1795 if ( ( pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1796 dwAccessOwner, 0, pSIDowner
1801 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1805 pFileACE -> dwMask = dwAccessOwnerDir;
1806 pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1807 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1811 FreeAce ( pFileACE );
1815 if ( dwAccessWorld != 0 )
1817 if ( ( pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1818 dwAccessWorld, 0, pSIDworld
1823 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1827 pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1828 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1832 FreeAce ( pFileACE );
1836 if ( dwAccessGroup != 0 ) {
1838 for ( i = 0; i < ( int )pTkGroups -> GroupCount; ++i ) {
1840 pSIDtemp = pTkGroups -> Groups[ i ].Sid;
1842 if ( !NtPredefinedSid ( pSIDtemp ) &&
1843 !EqualSid ( pSIDtemp, pSIDworld ) &&
1844 !EqualSid ( pSIDtemp, pTkPrimaryGroup -> PrimaryGroup ) &&
1845 IsValidSid ( pSIDtemp )
1848 if ( dwAccessGroup != 0 )
1850 if ( ( pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1851 dwAccessGroup, 0, pSIDtemp
1856 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1860 pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1861 AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1865 FreeAce ( pFileACE );
1875 if ( ( retVal = AllocSD () ) == NULL ) __leave;
1877 if ( !SetSecurityDescriptorDacl ( retVal, TRUE, pACL, TRUE ) ) __leave;
1887 if ( retVal != NULL )
1891 else if ( pACL != NULL )
1899 if ( hProcess != NULL ) CloseHandle ( hProcess );
1900 if ( pTkOwner != NULL ) FreeTokenInformation ( pTkOwner );
1901 if ( pTkGroups != NULL ) FreeTokenInformation ( pTkGroups );
1902 if ( pTkPrimaryGroup != NULL ) FreeTokenInformation ( pTkPrimaryGroup );
1903 if ( pfSD != NULL ) FreeFileSecurity ( pfSD );
1908 leave: ; // added for VisualAge
1913 } // end _osd_wnt_protection_to_sd */
1916 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1922 static void __fastcall _test_raise ( HANDLE hFile, Standard_CString str ) {
1924 if (hFile == INVALID_HANDLE_VALUE) {
1925 TCollection_AsciiString buff = "OSD_File :: ";
1927 buff += " (): wrong access";
1929 throw Standard_ProgramError(buff.ToCString());
1932 } // end _test_raise
1934 // Returns number of bytes in the string (including end \n, but excluding \r);
1936 static Standard_Integer __fastcall _get_line (Standard_PCharacter& buffer, DWORD dwBuffSize, LONG& theSeekPos)
1939 Standard_PCharacter ptr;
1941 buffer[ dwBuffSize ] = 0;
1944 while ( *ptr != 0 ) {
1948 ptr++ ; // jump newline char.
1950 theSeekPos = (LONG)(ptr - buffer - dwBuffSize);
1951 return (Standard_Integer)(ptr - buffer);
1953 else if ( *ptr == '\r' && ptr[ 1 ] == '\n' )
1955 *(ptr++) = '\n' ; // Substitue carriage return by newline.
1957 theSeekPos = (LONG)(ptr + 1 - buffer - dwBuffSize);
1958 return (Standard_Integer)(ptr - buffer);
1960 else if ( *ptr == '\r' && ptr[ 1 ] == 0 ) {
1961 *ptr = '\n' ; // Substitue carriage return by newline
1973 static int __fastcall _get_buffer (
1975 Standard_PCharacter& buffer,
1977 BOOL fPeek, BOOL fSocket
1987 flags = fPeek ? MSG_PEEK : 0;
1989 retVal = recv ( ( SOCKET )hChannel, buffer, ( int )dwSize, flags );
1991 if ( retVal == SOCKET_ERROR ) retVal = -1;
1997 if ( !PeekNamedPipe (
1998 hChannel, buffer, dwSize, &dwBytesRead, &dwDummy, &dwDummy
1999 ) && GetLastError () != ERROR_BROKEN_PIPE
2006 retVal = ( int )dwBytesRead;
2010 if ( !ReadFile ( hChannel, buffer, dwSize, &dwBytesRead, NULL ) )
2016 retVal = ( int )dwBytesRead;
2024 } // end _get_buffer
2027 static DWORD __fastcall _get_access_mask ( OSD_SingleProtection prt ) {
2041 retVal = FILE_GENERIC_READ;
2047 retVal = FILE_GENERIC_WRITE;
2053 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
2059 retVal = FILE_GENERIC_EXECUTE;
2065 retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
2071 retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2077 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2089 retVal = FILE_GENERIC_READ | DELETE;
2095 retVal = FILE_GENERIC_WRITE | DELETE;
2101 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
2107 retVal = FILE_GENERIC_EXECUTE | DELETE;
2113 retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE;
2119 retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2125 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2131 RAISE( "_get_access_mask (): incorrect parameter" );
2137 } // end _get_access_mask
2139 static DWORD __fastcall _get_dir_access_mask ( OSD_SingleProtection prt ) {
2153 retVal = GENERIC_READ;
2159 retVal = GENERIC_WRITE;
2165 retVal = GENERIC_READ | GENERIC_WRITE;
2171 retVal = GENERIC_EXECUTE;
2177 retVal = GENERIC_READ | GENERIC_EXECUTE;
2183 retVal = GENERIC_WRITE | GENERIC_EXECUTE;
2189 retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE;
2201 retVal = GENERIC_READ | DELETE;
2207 retVal = GENERIC_WRITE | DELETE;
2213 retVal = GENERIC_READ | GENERIC_WRITE | DELETE;
2219 retVal = GENERIC_EXECUTE | DELETE;
2225 retVal = GENERIC_READ | GENERIC_EXECUTE | DELETE;
2231 retVal = GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2237 retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2243 RAISE( "_get_dir_access_mask (): incorrect parameter" );
2249 } // end _get_dir_access_mask
2251 static HANDLE __fastcall _open_file (
2252 Standard_CString fName,
2254 DWORD dwOptions, LPBOOL fNew
2257 HANDLE retVal = INVALID_HANDLE_VALUE;
2258 DWORD dwDesiredAccess = 0;
2259 DWORD dwCreationDistribution;
2265 dwDesiredAccess = GENERIC_READ;
2271 dwDesiredAccess = GENERIC_WRITE;
2277 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
2283 RAISE( "_open_file (): incorrect parameter" );
2287 dwCreationDistribution = ( dwOptions != OPEN_NEW ) ? OPEN_EXISTING : CREATE_ALWAYS;
2289 // make wide character string from UTF-8
2290 TCollection_ExtendedString fNameW(fName, Standard_True);
2292 retVal = CreateFileW (
2293 fNameW.ToWideString(), dwDesiredAccess,
2294 FILE_SHARE_READ | FILE_SHARE_WRITE,
2295 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2298 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams = {};
2299 pCreateExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
2300 pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
2301 pCreateExParams.lpSecurityAttributes = NULL;
2302 pCreateExParams.hTemplateFile = NULL;
2303 retVal = CreateFile2 (
2304 fNameW.ToWideString(), dwDesiredAccess,
2305 FILE_SHARE_READ | FILE_SHARE_WRITE,
2306 dwCreationDistribution, &pCreateExParams
2309 if ( retVal == INVALID_HANDLE_VALUE &&
2310 dwOptions == OPEN_APPEND &&
2311 GetLastError () == ERROR_FILE_NOT_FOUND
2315 dwCreationDistribution = CREATE_ALWAYS;
2317 retVal = CreateFileW (
2318 fNameW.ToWideString(), dwDesiredAccess,
2319 FILE_SHARE_READ | FILE_SHARE_WRITE,
2320 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2323 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams2 = {};
2324 pCreateExParams2.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
2325 pCreateExParams2.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
2326 pCreateExParams2.lpSecurityAttributes = NULL;
2327 pCreateExParams2.hTemplateFile = NULL;
2328 retVal = CreateFile2(
2329 fNameW.ToWideString(), dwDesiredAccess,
2330 FILE_SHARE_READ | FILE_SHARE_WRITE,
2331 dwCreationDistribution, &pCreateExParams2
2343 Standard_Integer __fastcall _get_file_type (
2344 Standard_CString fName, HANDLE fileHandle
2347 Standard_Integer retVal = 0;
2350 fileType = (fileHandle == INVALID_HANDLE_VALUE ?
2351 FILE_TYPE_DISK : GetFileType (fileHandle));
2353 switch ( fileType ) {
2355 case FILE_TYPE_UNKNOWN:
2357 retVal = FLAG_SOCKET;
2361 case FILE_TYPE_DISK:
2363 // make wide character string from UTF-8
2364 TCollection_ExtendedString fNameW(fName, Standard_True);
2366 WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
2367 if (GetFileAttributesExW (fNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
2369 retVal = aFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FLAG_DIRECTORY : FLAG_FILE;
2373 retVal = 0x80000000;
2377 case FILE_TYPE_CHAR:
2379 retVal = FLAG_DEVICE;
2383 case FILE_TYPE_PIPE:
2393 } // end _get_file_type
2395 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2398 #define __leave return retVal
2402 // None of the existing security APIs are supported in a UWP applications
2403 BOOL __fastcall _osd_wnt_sd_to_protection (
2404 PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL fDir
2415 DWORD dwAccessOwner = 0;
2416 DWORD dwAccessGroup = 0;
2417 DWORD dwAccessAdmin = 0;
2418 DWORD dwAccessWorld = 0;
2419 BOOL retVal = FALSE;
2420 GET_PROT_FUNC _get_prot_func = fDir ? &_get_protection_dir : &_get_protection;
2424 if ( !GetSecurityDescriptorOwner ( pSD, &pSIDowner, &fDefaulted ) ) __leave;
2426 if ( !GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDefaulted ) ||
2430 if ( pSIDowner == NULL || pACL == NULL ) {
2432 SetLastError ( ERROR_NO_SECURITY_ON_OBJECT );
2437 pSIDadmin = AdminSid ();
2438 pSIDworld = WorldSid ();
2440 for ( i = 0; i < ( int )pACL -> AceCount; ++i ) {
2442 if ( GetAce ( pACL, i, &pACE ) ) {
2444 if ( EqualSid ( pSIDowner, GET_SID( pACE ) ) )
2446 dwAccessOwner = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2447 0 : *GET_MSK( pACE );
2449 else if ( EqualSid ( pSIDadmin, GET_SID( pACE ) ) )
2451 dwAccessAdmin = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2452 0 : *GET_MSK( pACE );
2454 else if ( EqualSid ( pSIDworld, GET_SID( pACE ) ) )
2456 dwAccessWorld = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2457 0 : *GET_MSK( pACE );
2461 dwAccessGroup = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2462 0 : *GET_MSK( pACE );
2469 ( *_get_prot_func ) ( dwAccessAdmin ),
2470 ( *_get_prot_func ) ( dwAccessOwner ),
2471 ( *_get_prot_func ) ( dwAccessGroup ),
2472 ( *_get_prot_func ) ( dwAccessWorld )
2482 leave: ; // added for VisualAge
2487 } // end _osd_wnt_sd_to_protection
2490 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2496 static OSD_SingleProtection __fastcall _get_protection ( DWORD mask ) {
2498 OSD_SingleProtection retVal;
2502 case FILE_GENERIC_READ:
2508 case FILE_GENERIC_WRITE:
2514 case FILE_GENERIC_READ | FILE_GENERIC_WRITE:
2520 case FILE_GENERIC_EXECUTE:
2526 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE:
2532 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2538 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2550 case FILE_GENERIC_READ | DELETE:
2556 case FILE_GENERIC_WRITE | DELETE:
2562 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE:
2568 case FILE_GENERIC_EXECUTE | DELETE:
2574 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE:
2580 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2586 case FILE_ALL_ACCESS:
2587 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2602 } // end _get_protection
2604 static OSD_SingleProtection __fastcall _get_protection_dir (DWORD theMask)
2612 case GENERIC_READ | GENERIC_WRITE:
2614 case GENERIC_EXECUTE:
2616 case GENERIC_READ | GENERIC_EXECUTE:
2618 case GENERIC_WRITE | GENERIC_EXECUTE:
2620 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE:
2624 case GENERIC_READ | DELETE:
2626 case GENERIC_WRITE | DELETE:
2628 case GENERIC_READ | GENERIC_WRITE | DELETE:
2630 case GENERIC_EXECUTE | DELETE:
2632 case GENERIC_READ | GENERIC_EXECUTE | DELETE:
2634 case GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2636 case FILE_ALL_ACCESS:
2637 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2642 // remote directories (on Samba server) have flags like for files
2643 return _get_protection (theMask);
2648 Standard_Boolean OSD_File::IsReadable()
2650 TCollection_AsciiString FileName ;
2653 myPath.SystemName(FileName) ;
2654 Channel = _open_file(FileName.ToCString(), OSD_ReadOnly, OPEN_OLD) ;
2655 if (Channel == INVALID_HANDLE_VALUE)
2656 return Standard_False ;
2658 CloseHandle (Channel) ;
2659 return Standard_True ;
2664 Standard_Boolean OSD_File::IsWriteable()
2666 TCollection_AsciiString FileName ;
2669 myPath.SystemName(FileName) ;
2670 Channel = _open_file(FileName.ToCString(), OSD_ReadWrite, OPEN_OLD) ;
2671 if (Channel == INVALID_HANDLE_VALUE)
2672 return Standard_False ;
2674 CloseHandle (Channel) ;
2675 return Standard_True ;
2679 Standard_Boolean OSD_File::IsExecutable()
2681 return IsReadable() ;
2683 // if (_access(FileName.ToCString(),0))
2688 // ---------------------------------------------------------------------
2689 // Destructs a file object (unlocks and closes file if it is open)
2690 // ---------------------------------------------------------------------
2692 OSD_File::~OSD_File()
2702 // ---------------------------------------------------------------------
2703 // Read lines in a file while it is increasing.
2704 // Each line is terminated with a <nl>.
2705 // ---------------------------------------------------------------------
2709 Standard_Boolean OSD_File::ReadLastLine(TCollection_AsciiString& aLine,const Standard_Integer aDelay,const Standard_Integer aNbTries)
2711 static Standard_Integer MaxLength = 1000 ;
2712 Standard_Integer Len ;
2713 Standard_Integer Count = aNbTries ;
2716 return Standard_False ;
2718 ReadLine(aLine, MaxLength, Len) ;
2719 if (!aLine.IsEmpty())
2720 return Standard_True ;
2722 return Standard_False ;
2723 OSD::SecSleep(aDelay) ;
2728 Standard_Boolean OSD_File::Edit()
2730 cout << "Function OSD_File::Edit() not yet implemented." << endl;
2731 return Standard_False ;