0027838: Foundation Classes - support wchar_t* input within TCollection_AsciiString...
[occt.git] / src / OSD / OSD_File.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //------------------------------------------------------------------------
16 //                    UNIX Part
17 //------------------------------------------------------------------------
18
19 #ifndef _WIN32
20
21
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>
31
32 const OSD_WhoAmI Iam = OSD_WFile;
33
34 #if defined (sun) || defined(SOLARIS)
35 #define POSIX
36 #else             
37 #define SYSV
38 #endif
39
40 #include <errno.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <sys/stat.h>
46
47 #define NEWLINE '\10';
48
49 // ---------------------------------------------------------------------
50 // Create an empty file object
51 // ---------------------------------------------------------------------
52
53 OSD_File::OSD_File():OSD_FileNode()
54 {
55  ImperativeFlag = Standard_False;
56  myLock         = OSD_NoLock;
57  myIO           = 0;
58  myMode         = OSD_ReadWrite;
59  myFILE         = (Standard_Address) NULL;
60  myFileChannel  = -1;
61  myFileHandle   = 0;
62 }
63
64 // ---------------------------------------------------------------------
65 // Create and initialize a file object
66 // ---------------------------------------------------------------------
67
68 OSD_File::OSD_File(const OSD_Path& Name):OSD_FileNode(Name)
69 {
70  ImperativeFlag = Standard_False;
71  myLock         = OSD_NoLock;
72  myIO           = 0;
73  myMode         = OSD_ReadWrite;
74  myFILE         = (Standard_Address) NULL;
75  myFileChannel  = -1;
76  myFileHandle   = 0;
77 }
78
79 // protect against occasional use of myFileHande in Linux code
80 #define myFileHandle myFileHandle_is_only_for_Windows
81
82 // ---------------------------------------------------------------------
83 // Build a file if it doesn't exist or create again if it already exists
84 // ---------------------------------------------------------------------
85
86 void OSD_File::Build(const OSD_OpenMode Mode,
87                      const OSD_Protection& Protect){
88  
89  Standard_Integer internal_prot;
90  Standard_Integer internal_mode = O_CREAT | O_TRUNC ;
91  TCollection_AsciiString aBuffer;
92
93  if (myPath.Name().Length()==0)
94   Standard_ProgramError::Raise("OSD_File::Build : no name was given");
95
96  if (myFileChannel != -1)
97   Standard_ProgramError::Raise("OSD_File::Build : file is already open");
98
99
100  myMode = Mode;
101
102  internal_prot = Protect.Internal();
103
104  const char* CMode = "r";
105
106  switch (Mode){
107   case OSD_ReadOnly:
108    internal_mode |= O_RDONLY;
109    CMode = "r";
110    break;
111   case OSD_WriteOnly:
112    internal_mode |= O_WRONLY;
113    CMode = "w";
114    break;
115   case OSD_ReadWrite:
116    internal_mode |= O_RDWR;
117    CMode = "w+";
118    break;
119  }
120
121  myPath.SystemName( aBuffer ); 
122  myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
123  if (myFileChannel >= 0) { 
124    myFILE = fdopen (myFileChannel, CMode);
125  }
126  else
127  /* Handle OPEN errors */
128
129    myError.SetValue (errno, Iam, "Open");
130
131 }
132
133
134
135 // ---------------------------------------------------------------------
136 // Append to an existing file
137 // ---------------------------------------------------------------------
138
139 void  OSD_File::Append(const OSD_OpenMode Mode,
140                        const OSD_Protection& Protect){
141
142  Standard_Integer internal_prot;
143  Standard_Integer internal_mode = O_APPEND;;
144  TCollection_AsciiString aBuffer;
145
146  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
147     Standard_ProgramError::Raise("OSD_File::Append : it is a directory");
148  } 
149  
150  if (myPath.Name().Length()==0)
151   Standard_ProgramError::Raise("OSD_File::Append : no name was given");
152
153  if (myFileChannel != -1)
154   Standard_ProgramError::Raise("OSD_File::Append : file is already open");
155
156  internal_prot = Protect.Internal();
157  myMode = Mode;
158  const char* CMode = "r";
159
160  switch (Mode){
161   case OSD_ReadOnly:
162    internal_mode |= O_RDONLY;
163    CMode = "r";
164    break;
165   case OSD_WriteOnly:
166    internal_mode |= O_WRONLY;
167    CMode = "a";
168    break;
169   case OSD_ReadWrite:
170    internal_mode |= O_RDWR;
171    CMode = "a+";
172    break;
173  }
174
175  // If file doesn't exist, creates it.
176
177  if (!Exists()) internal_mode |= O_CREAT;
178
179  myPath.SystemName ( aBuffer );
180  myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
181  if (myFileChannel >= 0)
182    myFILE = fdopen (myFileChannel, CMode);
183  else
184  /* Handle OPEN errors */
185
186    myError.SetValue (errno, Iam, "Open");
187 }
188
189 // ---------------------------------------------------------------------
190 // Open a file
191 // ---------------------------------------------------------------------
192
193 void  OSD_File::Open(const OSD_OpenMode Mode,
194                      const OSD_Protection& Protect){
195
196  Standard_Integer internal_prot;
197  Standard_Integer internal_mode = 0;
198  TCollection_AsciiString aBuffer;
199
200   if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
201     myError.SetValue (1, Iam, "Could not be open : it is a directory");
202   }
203
204  if (myPath.Name().Length()==0)
205   Standard_ProgramError::Raise("OSD_File::Open : no name was given");
206
207  if (myFileChannel != -1)
208   Standard_ProgramError::Raise("OSD_File::Open : file is already open");
209
210  internal_prot = Protect.Internal();
211  myMode = Mode;
212  const char* CMode = "r";
213
214  switch (Mode){
215   case OSD_ReadOnly:
216    internal_mode |= O_RDONLY;
217    CMode = "r";
218    break;
219   case OSD_WriteOnly:
220    internal_mode |= O_WRONLY;
221    CMode = "w";
222    break;
223   case OSD_ReadWrite:
224    internal_mode |= O_RDWR;
225    CMode = "w+";
226    break;
227  }
228
229  myPath.SystemName ( aBuffer );
230  myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
231  if (myFileChannel >= 0)
232    myFILE = fdopen (myFileChannel, CMode);
233  else
234  /* Handle OPEN errors */
235
236    myError.SetValue (errno, Iam, "Open");
237 }
238
239
240
241 // ---------------------------------------------------------------------
242 // ---------------------------------------------------------------------
243 void OSD_File::BuildTemporary(){
244
245  if ( IsOpen() )
246   Close();
247
248 #if defined(vax) || defined(__vms) || defined(VAXVMS)
249  FILE *fic;
250  int dummy;
251
252  fic = tmpfile();
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
257
258 #else 
259  char name[] = "/tmp/CSFXXXXXX";
260  myFileChannel = mkstemp( name );
261
262  TCollection_AsciiString aName ( name ) ;
263  OSD_Path aPath( aName ) ;
264
265  SetPath( aPath ) ;
266
267  myFILE = fdopen( myFileChannel, "w+" ) ;
268
269 #endif
270
271  myMode = OSD_ReadWrite;
272 }
273  
274
275
276 // ---------------------------------------------------------------------
277 // Read content of a file
278 // ---------------------------------------------------------------------
279  
280 void  OSD_File::Read(TCollection_AsciiString& Buffer, 
281                      const Standard_Integer Nbyte){
282  Standard_PCharacter readbuf;
283  int status;
284
285   if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
286     Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
287   }
288
289  if (myFileChannel == -1)
290   Standard_ProgramError::Raise("OSD_File::Read : file is not open");
291
292  if (Failed()) Perror();
293
294  if (myMode == OSD_WriteOnly)
295   Standard_ProgramError::Raise("OSD_File::Read : file is Write only");
296
297  if (Nbyte <= 0)
298   Standard_ProgramError::Raise("OSD_File::Read : Nbyte is null");
299
300  TCollection_AsciiString transfert(Nbyte,' ');
301  readbuf = (Standard_PCharacter)transfert.ToCString();  
302
303  status = read (myFileChannel, readbuf, Nbyte);
304  //
305  Buffer = transfert;  // Copy transfert to Buffer
306
307  if (status == -1) myError.SetValue (errno, Iam, "Read");
308  else
309  if ( status < Nbyte ) myIO = EOF;
310 }
311
312
313 // ---------------------------------------------------------------------
314 // Read a line from a file
315 // ---------------------------------------------------------------------
316
317 void OSD_File::ReadLine(TCollection_AsciiString& Buffer, 
318                         const Standard_Integer Nbyte,
319                         Standard_Integer& NByteRead)
320 {
321   Standard_PCharacter readbuf, abuffer;
322   //
323   if (OSD_File::KindOfFile() == OSD_DIRECTORY ) { 
324     Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
325   }
326   if (myFileChannel == -1){
327     Standard_ProgramError::Raise("OSD_File::ReadLine : file is not open");
328   }
329   if (Failed()) {
330     Perror();
331   }
332   if (myMode == OSD_WriteOnly) {
333     Standard_ProgramError::Raise("OSD_File::ReadLine : file is Write only");
334   }
335   if (Nbyte <= 0){
336     Standard_ProgramError::Raise("OSD_File::ReadLine : Nbyte is null");
337   }
338   //
339   TCollection_AsciiString transfert(Nbyte,' ');
340   readbuf = (Standard_PCharacter)transfert.ToCString();
341   //
342   abuffer = fgets(readbuf, Nbyte, (FILE *) myFILE);
343   //
344   if (abuffer == NULL) {
345     if (!feof((FILE *) myFILE)) {
346       myError.SetValue (errno, Iam, "ReadLine");
347       return;
348     }
349     else {
350       myIO = EOF;
351       Buffer.Clear();
352       NByteRead = 0 ;
353     }
354   }
355   else   {
356     NByteRead = (Standard_Integer)strlen(abuffer);
357     Buffer.SetValue(1,abuffer);  // Copy transfert to Buffer
358     Buffer.Trunc(NByteRead);
359   }
360 }
361 // -------------------------------------------------------------------------- 
362 // OSD::KindOfFile Retourne le type de fichier.
363 // -------------------------------------------------------------------------- 
364 OSD_KindFile OSD_File::KindOfFile ( ) const{
365 int status;
366 struct stat buffer;
367 TCollection_AsciiString FullName;
368 OSD_Path aPath;
369
370 Path(aPath);
371 aPath.SystemName (FullName);
372 status = stat (FullName.ToCString()  , &buffer );
373 if ( status == 0) {
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   ; }
379 }
380 return OSD_UNKNOWN   ; 
381
382 }
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)
389 {
390   int status;
391   
392   Readbyte = 0;
393   if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
394     Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
395   }
396  
397   if (myFileChannel == -1)
398     Standard_ProgramError::Raise("OSD_File::Read : file is not open");
399   
400   if (Failed()) Perror();
401   
402   if (myMode == OSD_WriteOnly)
403     Standard_ProgramError::Raise("OSD_File::Read : file is Write only");
404   
405   if (Nbyte <= 0)
406     Standard_ProgramError::Raise("OSD_File::Read : Nbyte is null");
407
408   if (Buffer == NULL)
409     Standard_ProgramError::Raise("OSD_File::Read : Buffer is null");
410   
411   status = read (myFileChannel, (char*) Buffer, Nbyte);
412   
413   if (status == -1) myError.SetValue (errno, Iam, "Read");
414   else{
415     if ( status < Nbyte ) myIO = EOF;
416     Readbyte = status;
417   }
418 }
419
420 // Write content of a file
421
422 void  OSD_File::Write(const TCollection_AsciiString &Buffer, 
423                       const Standard_Integer Nbyte){
424
425  Standard_CString writebuf;
426  int status;
427
428  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
429    Standard_ProgramError::Raise("OSD_File::Write : it is a directory");
430  }
431  
432  if (myFileChannel == -1)
433   Standard_ProgramError::Raise("OSD_File::Write : file is not open");
434
435  if (Failed()) Perror();
436
437  if (myMode == OSD_ReadOnly)
438   Standard_ProgramError::Raise("OSD_File::Write : file is Read only");
439
440  if (Nbyte <= 0)
441   Standard_ProgramError::Raise("OSD_File::Write : Nbyte is null");
442
443  writebuf = Buffer.ToCString();
444
445  status = write (myFileChannel, writebuf, Nbyte);
446
447  if ( status == -1) myError.SetValue (errno, Iam, "Write");
448  else
449  if ( status < Nbyte ) myIO = EOF;
450 }
451
452
453 void  OSD_File::Write(const Standard_Address   Buffer, 
454                       const Standard_Integer   Nbyte)
455 {
456
457   int status;
458   
459   if (myFileChannel == -1)
460     Standard_ProgramError::Raise("OSD_File::Write : file is not open");
461   
462   if (Failed()) Perror();
463   
464   if (myMode == OSD_ReadOnly)
465     Standard_ProgramError::Raise("OSD_File::Write : file is Read only");
466   
467   if (Nbyte <= 0)
468     Standard_ProgramError::Raise("OSD_File::Write : Nbyte is null");
469   
470   status = write (myFileChannel, (const char *)Buffer, Nbyte);
471   
472   if ( status == -1) myError.SetValue (errno, Iam, "Write");
473   else
474     if ( status < Nbyte ) myIO = EOF;
475 }
476
477
478
479
480
481 // Move file pointer to a specified position
482
483 void  OSD_File::Seek(const Standard_Integer Offset, 
484                      const OSD_FromWhere Whence){
485  int iwhere=0;
486
487  if (myFileChannel == -1)
488   Standard_ProgramError::Raise("OSD_File::Seek : file is not open");
489
490  if (Failed()) Perror();
491
492  switch (Whence){
493   case OSD_FromBeginning :
494     iwhere = SEEK_SET;
495     break;
496   case OSD_FromHere:
497     iwhere = SEEK_CUR;
498     break;
499   case OSD_FromEnd:
500     iwhere = SEEK_END;
501     break;
502   default :
503    myError.SetValue (EINVAL, Iam, "Seek");
504  }
505
506  off_t status = lseek (myFileChannel, Offset, iwhere);
507  if (status == -1) myError.SetValue (errno, Iam, "Seek");
508 }
509
510
511
512
513
514
515 // Close a file
516
517 void  OSD_File::Close(){
518  int status;
519
520  if (myFileChannel == -1)
521   Standard_ProgramError::Raise("OSD_File::Close : file is not open");
522
523  if (Failed()) Perror();
524
525  // note: it probably should be single call to fclose()...
526  status = close (myFileChannel);
527
528  if (status == -1) myError.SetValue (errno, Iam, "Close");
529  myFileChannel = -1;
530  if ( myFILE != NULL ) {
531    status = fclose ( (FILE*) myFILE );
532    myFILE = NULL;
533  }
534  myIO = 0;
535 }
536
537
538
539
540 // -------------------------------------------------------------------------- 
541 // Test if at end of file
542 // -------------------------------------------------------------------------- 
543
544 Standard_Boolean OSD_File::IsAtEnd(){
545  if (myFileChannel == -1)
546   Standard_ProgramError::Raise("OSD_File::IsAtEnd : file is not open");
547
548  if (myIO == EOF) return (Standard_True);
549  return (Standard_False);
550 }
551
552
553
554 /*void  OSD_File::Link(const TCollection_AsciiString& ToFile){
555  if (myFileChannel == -1)
556   Standard_ProgramError::Raise("OSD_File::Link : file is not open");
557
558  TCollection_AsciiString aBuffer;
559  myPath.SystemName ( aBuffer );
560  link ( aBuffer.ToCString(), ToFile.ToCString() );
561
562 }*/
563
564
565
566 void  OSD_File::SetLock(const OSD_LockType Lock){
567 int status;
568
569  if (myFileChannel == -1)
570   Standard_ProgramError::Raise("OSD_File::SetLock : file is not open");
571
572
573 #ifdef POSIX
574  int lock;
575  struct stat buf;
576
577  switch (Lock){
578   case OSD_ExclusiveLock :
579   case OSD_WriteLock     : lock = F_LOCK;
580                            break;
581   case OSD_ReadLock      : return;
582                            break;
583   default : myError.SetValue (EINVAL, Iam, "SetLock");
584             return;
585  }
586
587  if (fstat (myFileChannel, &buf) == -1) {
588   myError.SetValue (errno, Iam, "SetLock");
589   return;
590  }
591
592  status = lockf(myFileChannel, lock, buf.st_size);
593  if (status == -1) myError.SetValue (errno, Iam, "SetLock");
594  else myLock = Lock;
595
596 #else
597 #ifdef SYSV
598  struct stat  buf;
599  struct flock key;
600
601  switch (Lock){
602   case OSD_ExclusiveLock :
603   case OSD_WriteLock     : key.l_type = F_WRLCK;
604                            break;
605   case OSD_ReadLock      : key.l_type = F_RDLCK;
606                            break;
607   case OSD_NoLock : return;
608  // default : myError.SetValue (EINVAL, Iam, "SetLock");
609  }
610
611  key.l_whence = 0;
612  key.l_start = 0;
613  key.l_len = 0;
614
615  status = fcntl (myFileChannel, F_SETLKW, &key);
616  if (status == -1) myError.SetValue (errno, Iam, "SetLock");
617  else myLock = Lock;
618
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;
625  }
626
627 #else   /* BSD */
628  int lock;
629
630  switch (Lock){
631   case OSD_ExclusiveLock :
632   case OSD_WriteLock     : lock = F_WRLCK;
633                            break;
634   case OSD_ReadLock      : lock = F_RDLCK;
635                            break;
636   default : myError.SetValue (EINVAL, Iam, "SetLock");
637  }
638
639  status = flock (myFileChannel, lock);
640  if (status == -1) myError.SetValue (errno, Iam, "SetLock");
641  else myLock = Lock;
642 #endif // SysV
643 #endif // POSIX
644 }
645
646
647
648
649 // Remove a lock from a file
650
651 void  OSD_File::UnLock(){
652 int status;
653
654  if (myFileChannel == -1)
655   Standard_ProgramError::Raise("OSD_File::UnLock : file is not open");
656
657 #ifdef POSIX
658  struct stat buf;
659
660  if (fstat(myFileChannel, &buf) == -1) {
661   myError.SetValue(errno, Iam, "UnsetLock");
662   return;
663  }
664  
665  status = lockf(myFileChannel,F_ULOCK, buf.st_size);
666   if (status == -1) myError.SetValue (errno, Iam, "SetLock");
667
668 #else
669 #ifdef SYSV
670  struct stat  buf;
671  struct flock key;
672
673  if (ImperativeFlag){
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;
679  }
680  key.l_type = F_UNLCK;
681  status = fcntl (myFileChannel, F_SETLK, &key);
682  if (status == -1) myError.SetValue (errno, Iam, "UnSetLock");
683 #else
684
685  status = flock (myFileChannel, LOCK_UN);
686  if (status == -1) myError.SetValue (errno, Iam, "UnSetLock");
687 #endif
688 #endif // POSIX
689  else myLock = OSD_NoLock;
690 }
691
692
693
694
695
696 // Return lock of a file
697
698 OSD_LockType  OSD_File::GetLock(){
699  return(myLock);
700 }
701
702
703
704
705 // -------------------------------------------------------------------------- 
706 // Return size of a file
707 // -------------------------------------------------------------------------- 
708
709 Standard_Size  OSD_File::Size(){
710  struct stat buffer;
711  int status;
712
713  if (myPath.Name().Length()==0)
714   Standard_ProgramError::Raise("OSD_File::Size : empty file name");
715
716  TCollection_AsciiString aBuffer;
717  myPath.SystemName ( aBuffer );
718  status = stat( aBuffer.ToCString() ,&buffer );
719  if (status == -1) {
720   myError.SetValue (errno, Iam, "Size");
721   return 0;
722  }
723
724  return (Standard_Size)buffer.st_size;
725 }
726
727 // -------------------------------------------------------------------------- 
728 // Test if a file is open
729 // -------------------------------------------------------------------------- 
730
731 Standard_Boolean OSD_File::IsOpen()const{
732  return (myFileChannel != -1);
733 }
734
735
736 Standard_Boolean OSD_File::IsLocked(){
737  return(myLock != OSD_NoLock); 
738 }
739
740 Standard_Boolean OSD_File::IsReadable()
741 {
742   TCollection_AsciiString FileName ;
743
744   myPath.SystemName(FileName) ;
745
746   if (access(FileName.ToCString(),F_OK|R_OK))
747     return Standard_False;
748   else
749     return Standard_True;
750 }
751
752 Standard_Boolean OSD_File::IsWriteable()
753 {
754   TCollection_AsciiString FileName ;
755
756   myPath.SystemName(FileName) ;
757
758   if (access(FileName.ToCString(),F_OK|R_OK|W_OK))
759     return Standard_False;
760   else
761     return Standard_True;
762 }
763
764 Standard_Boolean OSD_File::IsExecutable()
765 {
766   TCollection_AsciiString FileName ;
767
768   myPath.SystemName(FileName) ;
769
770   if (access(FileName.ToCString(),F_OK|X_OK))
771     return Standard_False;
772   else
773     return Standard_True;
774 }
775
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);
781
782   // Return the old descriptor
783   return oldDescr;
784 }
785
786 void OSD_File::Rewind() { 
787     rewind((FILE*)myFILE); 
788 }
789
790 #else /* _WIN32 */
791
792 //------------------------------------------------------------------------
793 //-------------------  Windows NT sources for OSD_File -------------------
794 //------------------------------------------------------------------------
795
796 #include <windows.h>
797
798 #include <OSD_File.hxx>
799 #include <OSD_Protection.hxx>
800 #include <Standard_ProgramError.hxx>
801
802 #include <OSD_WNT_1.hxx>
803
804 #include <stdio.h>
805 #include <io.h>
806 #include <Standard_PCharacter.hxx>
807 #include <TCollection_ExtendedString.hxx>
808
809 #include <Strsafe.h>
810
811 #if defined(__CYGWIN32__) || defined(__MINGW32__)
812 #define VAC
813 #endif
814
815 #define ACE_HEADER_SIZE (  sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD )  )
816
817 #define RAISE( arg ) Standard_ProgramError :: Raise (  ( arg )  )
818 #define TEST_RAISE( arg ) _test_raise (  myFileHandle, ( arg )  )
819
820 #define OPEN_NEW    0
821 #define OPEN_OLD    1
822 #define OPEN_APPEND 2
823
824 void                            _osd_wnt_set_error        ( OSD_Error&, OSD_WhoAmI, ... );
825 #ifndef OCCT_UWP
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
829                                 );
830 static int       __fastcall _get_buffer(HANDLE, Standard_PCharacter&, DWORD, BOOL, BOOL);
831 #endif
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 );
837
838 static OSD_SingleProtection __fastcall _get_protection     ( DWORD );
839 static OSD_SingleProtection __fastcall _get_protection_dir ( DWORD );
840
841 typedef OSD_SingleProtection ( __fastcall *GET_PROT_FUNC ) ( DWORD );
842
843 Standard_Integer __fastcall _get_file_type ( Standard_CString, HANDLE );
844
845 // ---------------------------------------------------------------------
846 // Create an empty file object
847 // ---------------------------------------------------------------------
848
849 OSD_File :: OSD_File ()
850 {
851  ImperativeFlag = Standard_False;
852  myLock         = OSD_NoLock;
853  myIO           = 0;
854  myFileChannel  = -1;
855  myFileHandle   = INVALID_HANDLE_VALUE;
856 }  // end constructor ( 1 )
857
858 // ---------------------------------------------------------------------
859 // Create and initialize a file object
860 // ---------------------------------------------------------------------
861
862 OSD_File :: OSD_File ( const OSD_Path& Name ) : OSD_FileNode ( Name )
863 {
864  ImperativeFlag = Standard_False;
865  myLock         = OSD_NoLock;
866  myIO           = 0;
867  myPath         = Name;
868  myFileChannel  = -1;
869  myFileHandle   = INVALID_HANDLE_VALUE;
870 }  // end constructor ( 2 )
871
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
875 // standard handle.
876 // Example:
877 //    OSD_File aTmp;
878 //    aTmp.BuildTemporary();
879 //    int stdfd = _fileno(stdout);
880 //
881 //    int oldout = aTmp.Capture(stdfd);
882 //    cout << "Some output to the file" << endl;
883 //    cout << flush;
884 //    fflush(stdout);
885 //
886 //    _dup2(oldout, stdfd); // Restore standard output
887 //    aTmp.Close();
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);
892
893   if (0 > dFile)
894   {
895     _osd_wnt_set_error (  myError, OSD_WFile, myFileHandle );
896     return -1;
897   }
898
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);
903
904   // Return the old descriptor
905   return oldDescr;
906 }
907
908 void OSD_File::Rewind() { 
909   LARGE_INTEGER aDistanceToMove = { 0 };
910   aDistanceToMove.QuadPart = 0;
911   SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_BEGIN);
912 }
913
914 // protect against occasional use of myFileHande in Windows code
915 #define myFileChannel myFileChannel_is_only_for_Linux
916
917 // ---------------------------------------------------------------------
918 // Build a file if it doesn't exist or create again if it already exists
919 // ---------------------------------------------------------------------
920
921 void OSD_File :: Build ( const OSD_OpenMode Mode, const OSD_Protection& Protect) {
922
923  TCollection_AsciiString fName;
924
925  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
926    Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
927  }
928                                         
929  if (myFileHandle != INVALID_HANDLE_VALUE)
930
931   RAISE(  "OSD_File :: Build (): incorrect call - file already opened"  );
932
933  myMode = Mode;
934  myPath.SystemName ( fName );
935
936  if (  fName.IsEmpty ()  )
937
938   RAISE(  "OSD_File :: Build (): incorrent call - no filename given"  );
939
940  myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_NEW );
941
942  if (myFileHandle == INVALID_HANDLE_VALUE)
943
944   _osd_wnt_set_error ( myError, OSD_WFile );
945
946  else {
947 #ifndef OCCT_UWP
948   SetProtection ( Protect );
949 #else
950   (void)Protect;
951 #endif
952   myIO |= FLAG_FILE;
953
954  }  // end else
955
956 }  // end OSD_File :: Build
957
958
959
960 // ---------------------------------------------------------------------
961 // Open a file
962 // ---------------------------------------------------------------------
963
964 void OSD_File :: Open (const OSD_OpenMode Mode, const OSD_Protection& /*Protect*/)
965 {
966
967  TCollection_AsciiString fName;
968
969
970  if (myFileHandle != INVALID_HANDLE_VALUE)
971
972   RAISE(  "OSD_File :: Open (): incorrect call - file already opened"  );
973
974  myMode = Mode;
975  myPath.SystemName ( fName );
976
977  if (  fName.IsEmpty ()  )
978
979   RAISE(  "OSD_File :: Open (): incorrent call - no filename given"  );
980
981  myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_OLD );
982
983  if (myFileHandle == INVALID_HANDLE_VALUE) {
984
985    _osd_wnt_set_error ( myError, OSD_WFile );
986  }
987  else
988    {
989      myIO |= _get_file_type (  fName.ToCString (), myFileHandle  );
990    }
991 }  // end OSD_File :: Open
992
993 // ---------------------------------------------------------------------
994 // Append to an existing file
995 // ---------------------------------------------------------------------
996
997 void OSD_File :: Append ( const OSD_OpenMode Mode, const OSD_Protection& Protect) {
998
999  BOOL                    fNew = FALSE;
1000  TCollection_AsciiString fName;
1001
1002  if (myFileHandle != INVALID_HANDLE_VALUE)
1003
1004   RAISE(  "OSD_File :: Append (): incorrect call - file already opened"  );
1005
1006  myMode = Mode;
1007  myPath.SystemName ( fName );
1008
1009  if (  fName.IsEmpty ()  )
1010
1011   RAISE(  "OSD_File :: Append (): incorrent call - no filename given"  );
1012
1013  myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_APPEND, &fNew );
1014
1015  if (myFileHandle == INVALID_HANDLE_VALUE)
1016
1017   _osd_wnt_set_error ( myError, OSD_WFile );
1018
1019  else {
1020
1021   if ( !fNew ) {
1022
1023    myIO |= _get_file_type (  fName.ToCString (), myFileHandle  );
1024    Seek ( 0, OSD_FromEnd );
1025
1026   } else {
1027 #ifndef OCCT_UWP
1028     SetProtection ( Protect );
1029 #else
1030     (void)Protect;
1031 #endif
1032    myIO |= FLAG_FILE;
1033   
1034   }  // end else
1035
1036  }  // end else;
1037
1038 }  // end OSD_File :: Append
1039
1040 // ---------------------------------------------------------------------
1041 // Read content of a file
1042 // ---------------------------------------------------------------------
1043  
1044 void OSD_File :: Read (
1045                   TCollection_AsciiString& Buffer, const Standard_Integer Nbyte
1046                  ) {
1047
1048  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
1049 #ifdef OCCT_DEBUG
1050    cout << " OSD_File::Read : it is a directory " << endl;
1051 #endif
1052    return ;
1053 //   Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1054  }
1055                                         
1056  Standard_Integer NbyteRead;
1057
1058  TEST_RAISE(  "Read"  );
1059      
1060  char* buff = new Standard_Character[ Nbyte + 1 ];
1061
1062  Read ( buff, Nbyte, NbyteRead );
1063
1064  buff[ NbyteRead ] = 0;
1065
1066  if ( NbyteRead != 0 )
1067
1068   Buffer = buff;
1069
1070  else
1071
1072   Buffer.Clear ();
1073
1074  delete [] buff;
1075
1076 }  // end OSD_File :: Read
1077
1078 // ---------------------------------------------------------------------
1079 // Read a line from a file
1080 // ---------------------------------------------------------------------
1081
1082 // Modified so that we have <nl> at end of line if we have read <nl> or <cr>
1083 // in the file.
1084 // by LD 17 dec 98 for B4.4
1085
1086 void OSD_File :: ReadLine (
1087                   TCollection_AsciiString& Buffer,
1088                   const Standard_Integer NByte, Standard_Integer& NbyteRead
1089                  ) {
1090
1091  DWORD              dwBytesRead;
1092  DWORD              dwDummy;
1093  Standard_Character peekChar;
1094  Standard_PCharacter ppeekChar;
1095  Standard_PCharacter cBuffer;
1096  LONG               aSeekPos;
1097
1098  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
1099    Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1100  }
1101                                         
1102  TEST_RAISE(  "ReadLine"  );              
1103
1104  if (  myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE )  )
1105
1106   RAISE(  "OSD_File :: ReadLine (): attempt to read from write only pipe"  );
1107
1108                                         // +----> leave space for end-of-string
1109                                         // |       plus <CR><LF> sequence      
1110                                         // |
1111
1112  ppeekChar=&peekChar;
1113  cBuffer = new Standard_Character[ NByte + 3 ];
1114
1115  if ( myIO & FLAG_FILE ) {
1116  
1117   if (!ReadFile (myFileHandle, cBuffer, NByte, &dwBytesRead, NULL)) {  // an error occured
1118
1119    _osd_wnt_set_error ( myError, OSD_WFile );   
1120    Buffer.Clear ();
1121    NbyteRead = 0;
1122    
1123   } else if ( dwBytesRead == 0 ) {  // end-of-file reached
1124    
1125    Buffer.Clear ();
1126    NbyteRead = 0;
1127    myIO |= FLAG_EOF;
1128    
1129   } else {
1130    myIO &= ~FLAG_EOF ;  // if the file increased since last read (LD)
1131    NbyteRead = _get_line (cBuffer, dwBytesRead, aSeekPos);
1132
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)) {
1136     
1137      _osd_wnt_set_error ( myError, OSD_WFile );
1138
1139     } else if ( dwDummy != 0 ) {  // end-of-file reached ?
1140
1141       if (peekChar != '\n')  // if we did not get a <CR><LF> sequence
1142       {
1143         // adjust file position
1144         LARGE_INTEGER aDistanceToMove = { 0 };
1145         aDistanceToMove.QuadPart = -1;
1146         SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
1147       }
1148     } else
1149      myIO |= FLAG_EOF;
1150
1151     NbyteRead = dwBytesRead;
1152
1153    } else if ( aSeekPos != 0 )
1154    {
1155      LARGE_INTEGER aDistanceToMove = { 0 };
1156      aDistanceToMove.QuadPart = aSeekPos;
1157      SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
1158    }
1159
1160   }  // end else
1161    
1162  } else if ( myIO & FLAG_SOCKET || myIO & FLAG_PIPE || myIO & FLAG_NAMED_PIPE ) {
1163 #ifndef OCCT_UWP
1164   dwBytesRead = (DWORD)_get_buffer (myFileHandle, cBuffer, 
1165                                     (DWORD)NByte, TRUE, myIO & FLAG_SOCKET);
1166
1167   if (  ( int )dwBytesRead == -1  ) { // an error occured
1168
1169    _osd_wnt_set_error ( myError, OSD_WFile );
1170    Buffer.Clear ();
1171    NbyteRead = 0;
1172
1173   } else if ( dwBytesRead == 0 )  { // connection closed - set end-of-file flag
1174
1175    Buffer.Clear ();
1176    NbyteRead = 0;
1177    myIO |= FLAG_EOF;
1178
1179   } else {
1180
1181    NbyteRead = _get_line (cBuffer, dwBytesRead, aSeekPos);
1182
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.
1186
1187     dwDummy = _get_buffer (myFileHandle, ppeekChar, 1, TRUE, myIO & FLAG_SOCKET);
1188     if (  ( int )dwDummy == -1  ) {  // an error occured
1189    
1190      _osd_wnt_set_error ( myError, OSD_WFile );
1191
1192     } else if ( dwDummy != 0 ) {  // connection closed ?
1193
1194      if ( peekChar == '\n' )  // we got a <CR><LF> sequence
1195
1196        dwBytesRead++ ;  // (LD) we have to jump <LF>
1197     } else
1198
1199      myIO |= FLAG_EOF;
1200
1201    } else if (aSeekPos != 0)
1202    {
1203      dwBytesRead = dwBytesRead + aSeekPos;
1204    }
1205
1206    // Don't rewrite datas in cBuffer.
1207
1208    Standard_PCharacter cDummyBuffer = new Standard_Character[ NByte + 3 ];
1209
1210    // remove pending input
1211    _get_buffer (myFileHandle, cDummyBuffer, dwBytesRead, FALSE, myIO & FLAG_SOCKET);
1212    delete [] cDummyBuffer ;
1213
1214   }  // end else
1215 #endif
1216  } else
1217
1218   RAISE(  "OSD_File :: ReadLine (): incorrect call - file is a directory"  );
1219
1220  if (  !Failed () && !IsAtEnd ()  )
1221
1222   Buffer = cBuffer;
1223
1224  delete [] (Standard_PCharacter)cBuffer;
1225
1226 }  // end OSD_File :: ReadLine
1227
1228 // -------------------------------------------------------------------------- 
1229 // Read content of a file
1230 // -------------------------------------------------------------------------- 
1231
1232 void OSD_File :: Read (
1233                   const Standard_Address Buffer,
1234                   const Standard_Integer Nbyte, Standard_Integer& Readbyte
1235                  ) {
1236
1237  DWORD dwBytesRead;
1238
1239  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
1240    Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1241  }
1242                                         
1243  TEST_RAISE(  "Read"  );
1244
1245  if (  myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE )  )
1246
1247   RAISE(  "OSD_File :: Read (): attempt to read from write only pipe"  );
1248
1249  if (!ReadFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesRead, NULL)) {
1250  
1251   _osd_wnt_set_error ( myError, OSD_WFile );
1252   dwBytesRead = 0;
1253  
1254  } else if ( dwBytesRead == 0 )
1255
1256   myIO |= FLAG_EOF;
1257
1258  else
1259
1260   myIO &= ~FLAG_EOF;
1261
1262  Readbyte = ( Standard_Integer )dwBytesRead;
1263
1264 }  // end OSD_File :: Read
1265
1266 void OSD_File :: Write (
1267                   const TCollection_AsciiString& Buffer,
1268                   const Standard_Integer Nbyte
1269                  ) {
1270
1271  Write (  ( Standard_Address )Buffer.ToCString (), Nbyte  );
1272
1273 }  // end OSD_File :: Write
1274
1275 // -------------------------------------------------------------------------- 
1276 // Write content of a file
1277 // -------------------------------------------------------------------------- 
1278
1279 void OSD_File :: Write (
1280                   const Standard_Address Buffer,
1281                   const Standard_Integer Nbyte
1282                  ) {
1283
1284  DWORD dwBytesWritten;
1285
1286  TEST_RAISE(  "Write"  );
1287
1288  if ( myIO & FLAG_PIPE && myIO & FLAG_READ_PIPE )
1289
1290   RAISE(  "OSD_File :: Write (): attempt to write to read only pipe"  );
1291
1292  if (!WriteFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesWritten, NULL) || 
1293      dwBytesWritten != (DWORD)Nbyte)
1294
1295   _osd_wnt_set_error ( myError, OSD_WFile );
1296
1297 }  // end OSD_File :: Write
1298
1299 void OSD_File :: Seek (
1300                   const Standard_Integer Offset, const OSD_FromWhere Whence
1301                  ) {
1302
1303  DWORD dwMoveMethod = 0;
1304
1305  TEST_RAISE(  "Seek"  );
1306
1307  if ( myIO & FLAG_FILE || myIO & FLAG_DIRECTORY ) {
1308
1309   switch ( Whence ) {
1310   
1311    case OSD_FromBeginning:
1312
1313     dwMoveMethod = FILE_BEGIN;
1314
1315    break;
1316
1317    case OSD_FromHere:
1318
1319     dwMoveMethod = FILE_CURRENT;
1320
1321    break;
1322
1323    case OSD_FromEnd:
1324
1325     dwMoveMethod = FILE_END;
1326
1327    break;
1328
1329    default:
1330
1331     RAISE(  "OSD_File :: Seek (): invalid parameter"  );
1332   
1333   }  // end switch
1334   LARGE_INTEGER aDistanceToMove, aNewFilePointer = { 0 };
1335   aDistanceToMove.QuadPart = Offset;
1336
1337   if (!SetFilePointerEx(myFileHandle, aDistanceToMove, &aNewFilePointer, dwMoveMethod))
1338
1339    _osd_wnt_set_error ( myError, OSD_WFile );
1340   
1341  }  // end if
1342
1343  myIO &= ~FLAG_EOF;
1344
1345 }  // end OSD_File :: Seek
1346
1347 // -------------------------------------------------------------------------- 
1348 // Close a file
1349 // -------------------------------------------------------------------------- 
1350
1351 void OSD_File :: Close () {
1352
1353  TEST_RAISE(  "Close"  );
1354
1355  CloseHandle (myFileHandle);
1356
1357  myFileHandle = INVALID_HANDLE_VALUE;
1358  myIO          = 0;
1359
1360 }  // end OSD_File :: Close
1361
1362 // -------------------------------------------------------------------------- 
1363 // Test if at end of file
1364 // -------------------------------------------------------------------------- 
1365
1366 Standard_Boolean OSD_File :: IsAtEnd () {
1367
1368  TEST_RAISE(  "IsAtEnd"  );
1369
1370  if (myIO & FLAG_EOF)
1371    return Standard_True ;
1372  return Standard_False ;
1373
1374 }  // end OSD_File :: IsAtEnd
1375
1376 OSD_KindFile OSD_File :: KindOfFile () const {
1377
1378  OSD_KindFile     retVal;
1379  Standard_Integer flags;
1380
1381  if (myFileHandle == INVALID_HANDLE_VALUE) {
1382
1383   TCollection_AsciiString fName;
1384
1385   myPath.SystemName ( fName );
1386
1387   if (  fName.IsEmpty ()  )
1388
1389    RAISE(  "OSD_File :: KindOfFile (): incorrent call - no filename given"  );
1390
1391   flags = _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE);
1392
1393  } else
1394
1395   flags = myIO;
1396
1397  switch ( flags & FLAG_TYPE ) {
1398  
1399   case FLAG_FILE:
1400
1401    retVal = OSD_FILE;
1402
1403   break;
1404
1405   case FLAG_DIRECTORY:
1406
1407    retVal = OSD_DIRECTORY;
1408
1409   break;
1410
1411   case FLAG_SOCKET:
1412
1413    retVal = OSD_SOCKET;
1414
1415   break;
1416
1417   default:
1418
1419    retVal = OSD_UNKNOWN;
1420  
1421  }  // end switch
1422
1423  return retVal;
1424
1425 }  // end OSD_File :: KindOfFile
1426
1427 //-------------------------------------------------debutpri???980424
1428
1429 typedef struct _osd_wnt_key {
1430
1431                 HKEY   hKey;
1432                 const char* keyPath;
1433
1434                } OSD_WNT_KEY;
1435
1436
1437  void OSD_File::BuildTemporary () {
1438
1439  OSD_Protection prt;
1440  wchar_t        tmpPath[ MAX_PATH ];
1441  BOOL           fOK = FALSE;
1442
1443 // Windows Registry not supported by UWP
1444 #ifndef OCCT_UWP
1445  HKEY           hKey;
1446
1447  OSD_WNT_KEY    regKey[ 2 ] = {
1448  
1449                  { HKEY_LOCAL_MACHINE,
1450                    "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
1451                  },
1452                  { HKEY_USERS,
1453                    ".DEFAULT\\Environment"
1454                  }
1455  
1456                 };
1457  
1458  for ( int i = 0; i < 2; ++i ) {
1459
1460   if (  RegOpenKeyEx (
1461          regKey[ i ].hKey, regKey[ i ].keyPath, 0, KEY_QUERY_VALUE, &hKey
1462        ) == ERROR_SUCCESS
1463   ) {
1464   
1465    DWORD dwType;
1466    DWORD dwSize = 0;
1467
1468    if (  RegQueryValueExW (
1469           hKey, L"TEMP", NULL, &dwType, NULL, &dwSize
1470          ) == ERROR_SUCCESS
1471    ) {
1472   
1473      wchar_t* kVal = (wchar_t*)HeapAlloc (
1474                              GetProcessHeap (), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
1475                              dwSize + sizeof (wchar_t)
1476                             );
1477
1478      RegQueryValueExW (  hKey, L"TEMP", NULL, &dwType, ( LPBYTE )kVal, &dwSize  );
1479
1480      if ( dwType == REG_EXPAND_SZ )
1481     
1482       ExpandEnvironmentStringsW ( kVal, tmpPath, MAX_PATH );
1483
1484      else
1485
1486        StringCchCopyW (tmpPath, _countof(tmpPath), kVal);
1487
1488     HeapFree (  GetProcessHeap (), 0, ( LPVOID )kVal  );
1489     fOK = TRUE;
1490
1491    }  // end if
1492
1493    RegCloseKey ( hKey );
1494
1495   }  // end if
1496
1497   if ( fOK ) break;
1498
1499  }  // end for
1500 #else
1501  if (GetTempPathW(_countof(tmpPath), tmpPath))
1502    fOK = TRUE;
1503 #endif
1504  if ( !fOK )       StringCchCopyW(tmpPath, _countof(tmpPath), L"./");
1505
1506  GetTempFileNameW ( tmpPath, L"CSF", 0, tmpPath );
1507
1508  if ( IsOpen() )
1509   Close();
1510
1511  char tmpPathA[MAX_PATH];
1512  WideCharToMultiByte(CP_UTF8, 0, tmpPath, -1, tmpPathA, sizeof(tmpPathA), NULL, NULL);
1513  SetPath(OSD_Path(tmpPathA));
1514
1515  Build   (  OSD_ReadWrite, prt    );
1516 }  // end OSD_File :: BuildTemporary
1517
1518 //-------------------------------------------------finpri???980424
1519
1520 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1521 #define __try
1522 #define __finally
1523 #define __leave return
1524 #endif
1525
1526 void OSD_File :: SetLock ( const OSD_LockType Lock ) {
1527
1528  DWORD      dwFlags;
1529  OVERLAPPED ovlp;
1530
1531  TEST_RAISE(  "SetLock"  );
1532  
1533  ZeroMemory (  &ovlp, sizeof ( OVERLAPPED )  );
1534
1535  __try {
1536
1537   if (  ( myLock = Lock ) == OSD_NoLock  ) {
1538
1539    UnLock ();
1540    __leave;
1541
1542   } else if ( myLock == OSD_ReadLock || myLock == OSD_ExclusiveLock ) {
1543
1544    dwFlags = LOCKFILE_EXCLUSIVE_LOCK;
1545
1546   } else
1547
1548    dwFlags = 0;
1549
1550   LARGE_INTEGER aSize;
1551   aSize.QuadPart = Size();
1552   if (!LockFileEx (myFileHandle, dwFlags, 0, aSize.LowPart, aSize.HighPart, &ovlp)) {
1553
1554    _osd_wnt_set_error ( myError, OSD_WFile );
1555    __leave;
1556
1557   }  // end if
1558
1559   ImperativeFlag = Standard_True;
1560
1561  }  // end __try
1562
1563  __finally {}
1564
1565 #ifdef VAC
1566 leave: ;         // added for VisualAge
1567 #endif
1568 }  // end OSD_File :: SetLock
1569
1570 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1571 #undef __try
1572 #undef __finally
1573 #undef __leave
1574 #endif
1575
1576 void OSD_File :: UnLock () {
1577
1578  TEST_RAISE(  "Unlock"  );
1579
1580  if ( ImperativeFlag ) {
1581  
1582   LARGE_INTEGER aSize;
1583   aSize.QuadPart = Size();
1584
1585   OVERLAPPED anOverlappedArea;
1586   anOverlappedArea.Offset = 0;
1587   anOverlappedArea.OffsetHigh = 0;
1588
1589   if (!UnlockFileEx(myFileHandle, 0, aSize.LowPart, aSize.HighPart,&anOverlappedArea))
1590    _osd_wnt_set_error ( myError, OSD_WFile );
1591
1592   ImperativeFlag = Standard_False;
1593  
1594  }  // end if
1595
1596 }  // end OSD_File :: UnLock
1597
1598 OSD_LockType OSD_File :: GetLock () {
1599
1600  return myLock;
1601
1602 }  // end OSD_File :: GetLock
1603
1604 Standard_Boolean OSD_File :: IsLocked () {
1605
1606  TEST_RAISE(  "IsLocked"  );
1607
1608  return ImperativeFlag;
1609
1610 }  // end OSD_File :: IsLocked
1611
1612
1613 // -------------------------------------------------------------------------- 
1614 // Return size of a file
1615 // -------------------------------------------------------------------------- 
1616
1617 Standard_Size OSD_File::Size()
1618 {
1619   TEST_RAISE("Size");
1620 #if (_WIN32_WINNT >= 0x0500)
1621   LARGE_INTEGER aSize;
1622   aSize.QuadPart = 0;
1623   if (GetFileSizeEx (myFileHandle, &aSize) == 0)
1624   {
1625     _osd_wnt_set_error (myError, OSD_WFile);
1626   }
1627   return (Standard_Size)aSize.QuadPart;
1628 #else
1629   DWORD aSize = GetFileSize (myFileHandle, NULL);
1630   if (aSize == INVALID_FILE_SIZE)
1631   {
1632     _osd_wnt_set_error (myError, OSD_WFile);
1633   }
1634   return aSize;
1635 #endif
1636 }
1637
1638 // -------------------------------------------------------------------------- 
1639 // Test if a file is open
1640 // -------------------------------------------------------------------------- 
1641
1642 Standard_Boolean OSD_File :: IsOpen () const {
1643
1644  return myFileHandle != INVALID_HANDLE_VALUE;
1645
1646 }  // end OSD_File :: IsOpen
1647
1648 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1649 #define __try
1650 #define __finally
1651 #define __leave return retVal
1652 #endif
1653
1654 #ifndef OCCT_UWP
1655 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd (
1656                                  const OSD_Protection& prot, BOOL fDir, const wchar_t* fName
1657                                 ) {
1658
1659  int                  i, j;
1660  BOOL                 fOK      = FALSE;
1661  PACL                 pACL     = NULL;
1662  HANDLE               hProcess = NULL;
1663  PSID                 pSIDowner;
1664  PSID                 pSIDadmin;
1665  PSID                 pSIDworld;
1666  PSID                 pSIDtemp;
1667  DWORD                dwAccessAdmin;
1668  DWORD                dwAccessGroup;
1669  DWORD                dwAccessOwner;
1670  DWORD                dwAccessWorld;
1671  DWORD                dwAccessAdminDir;
1672 // DWORD                dwAccessGroupDir;
1673  DWORD                dwAccessOwnerDir;
1674 // DWORD                dwAccessWorldDir;
1675  DWORD                dwACLsize       = sizeof ( ACL );
1676  DWORD                dwIndex         = 0;
1677  PTOKEN_OWNER         pTkOwner        = NULL;
1678  PTOKEN_GROUPS        pTkGroups       = NULL;
1679  PTOKEN_PRIMARY_GROUP pTkPrimaryGroup = NULL;
1680  PSECURITY_DESCRIPTOR retVal = NULL;
1681  PSECURITY_DESCRIPTOR pfSD = NULL;
1682  BOOL                 fDummy;
1683  PFILE_ACE            pFileACE;
1684
1685  __try {
1686
1687   j = fDir ? 1 : 0;
1688
1689   if (  !OpenProcessToken (
1690           GetCurrentProcess (), TOKEN_QUERY, &hProcess
1691          )
1692   ) __leave;
1693
1694   if (   (  pTkGroups = ( PTOKEN_GROUPS )GetTokenInformationEx (
1695                                           hProcess, TokenGroups
1696                                          )
1697          ) == NULL
1698   ) __leave; 
1699   
1700   if (   (  pTkOwner = ( PTOKEN_OWNER )GetTokenInformationEx (
1701                                         hProcess, TokenOwner
1702                                        )
1703          ) == NULL
1704   ) __leave;
1705
1706   if (   (  pTkPrimaryGroup = ( PTOKEN_PRIMARY_GROUP )GetTokenInformationEx (
1707                                                        hProcess, TokenPrimaryGroup
1708                                                       )
1709          ) == NULL
1710   ) __leave;
1711
1712
1713 retry:
1714   if ( fName == NULL )
1715
1716    pSIDowner = pTkOwner -> Owner;
1717
1718   else {
1719
1720    pfSD = GetFileSecurityEx ( fName, OWNER_SECURITY_INFORMATION );
1721
1722    if (  pfSD == NULL || !GetSecurityDescriptorOwner ( pfSD, &pSIDowner, &fDummy )  ) {
1723
1724     fName = NULL;
1725     goto retry;
1726
1727    }  // end if
1728
1729   }  // end else
1730
1731   pSIDadmin = AdminSid ();
1732   pSIDworld = WorldSid ();
1733
1734   dwAccessAdmin = _get_access_mask (  prot.System ()  );
1735   dwAccessGroup = _get_access_mask (  prot.Group  ()  );
1736   dwAccessOwner = _get_access_mask (  prot.User   ()  );
1737   dwAccessWorld = _get_access_mask (  prot.World  ()  );
1738
1739   dwAccessAdminDir = _get_dir_access_mask (  prot.System ()  );
1740 //  dwAccessGroupDir = _get_dir_access_mask (  prot.Group  ()  );
1741   dwAccessOwnerDir = _get_dir_access_mask (  prot.User   ()  );
1742 //  dwAccessWorldDir = _get_dir_access_mask (  prot.World  ()  );
1743
1744   if (  dwAccessGroup != 0  ) {
1745                                              
1746    for ( i = 0; i < ( int )pTkGroups -> GroupCount; ++i ) {
1747
1748     pSIDtemp = pTkGroups -> Groups[ i ].Sid;
1749
1750     if (  !NtPredefinedSid ( pSIDtemp                                  ) &&
1751           !EqualSid        ( pSIDtemp, pSIDworld                       ) &&
1752           !EqualSid        ( pSIDtemp, pTkPrimaryGroup -> PrimaryGroup ) &&
1753            IsValidSid      ( pSIDtemp                                  )
1754     )
1755
1756      dwACLsize += ( (  GetLengthSid ( pSIDtemp ) + ACE_HEADER_SIZE  ) << j );
1757
1758    }  // end for
1759   
1760   }  // end if
1761
1762   dwACLsize += (  ( ( GetLengthSid ( pSIDowner ) + ACE_HEADER_SIZE ) << j ) +
1763                   ( ( GetLengthSid ( pSIDadmin ) + ACE_HEADER_SIZE ) << j ) +
1764                   ( ( GetLengthSid ( pSIDworld ) + ACE_HEADER_SIZE ) << j )
1765                );
1766
1767   if (   (  pACL = CreateAcl ( dwACLsize )  ) == NULL   ) __leave;
1768
1769   if ( dwAccessAdmin != 0 )
1770
1771    if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1772                                       dwAccessAdmin, 0,
1773                                       pSIDadmin
1774                                      )
1775            ) != NULL
1776    ) {
1777
1778     AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1779
1780     if ( fDir ) {
1781
1782      pFileACE -> dwMask = dwAccessAdminDir;
1783      pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1784      AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1785
1786     }  // end if
1787
1788     FreeAce ( pFileACE );
1789
1790    }  // end if
1791
1792   if ( dwAccessOwner != 0 )
1793
1794    if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1795                                       dwAccessOwner, 0, pSIDowner
1796                                      )
1797           ) != NULL
1798    ) {
1799
1800     AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1801
1802     if ( fDir ) {
1803
1804      pFileACE -> dwMask = dwAccessOwnerDir;
1805      pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1806      AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1807    
1808     }  // end if
1809
1810     FreeAce ( pFileACE );
1811
1812    }  // end if
1813
1814   if ( dwAccessWorld != 0 )
1815
1816    if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1817                                       dwAccessWorld, 0, pSIDworld
1818                                      )
1819           ) != NULL
1820    ) {
1821
1822     AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1823
1824     if ( fDir ) {
1825
1826      pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1827      AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1828    
1829     }  // end if
1830
1831     FreeAce ( pFileACE );
1832
1833    }  // end if
1834
1835   if ( dwAccessGroup != 0 ) {
1836
1837    for ( i = 0; i < ( int )pTkGroups -> GroupCount; ++i ) {
1838
1839     pSIDtemp = pTkGroups -> Groups[ i ].Sid;
1840
1841     if (  !NtPredefinedSid ( pSIDtemp                                  ) &&
1842           !EqualSid        ( pSIDtemp, pSIDworld                       ) &&
1843           !EqualSid        ( pSIDtemp, pTkPrimaryGroup -> PrimaryGroup ) &&
1844            IsValidSid      ( pSIDtemp                                  )
1845     ) {
1846
1847      if ( dwAccessGroup != 0 )
1848
1849       if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1850                                          dwAccessGroup, 0, pSIDtemp
1851                                         )
1852              ) != NULL
1853       ) {
1854
1855        AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1856
1857       if ( fDir ) {
1858
1859        pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1860        AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1861    
1862       }  // end if
1863
1864       FreeAce ( pFileACE );
1865
1866      }  // end if
1867
1868     }  // end if
1869
1870    }  // end for
1871
1872   }  // end if
1873
1874   if (   (  retVal = AllocSD ()  ) == NULL   ) __leave;
1875
1876   if (  !SetSecurityDescriptorDacl ( retVal, TRUE, pACL, TRUE )  ) __leave;
1877
1878   fOK = TRUE;
1879
1880  }  // end __try
1881
1882  __finally {
1883  
1884   if ( !fOK ) {
1885
1886    if ( retVal != NULL )
1887        
1888     FreeSD ( retVal );
1889
1890    else if ( pACL != NULL )
1891
1892     FreeAcl ( pACL );
1893
1894    retVal = NULL;
1895   
1896   }  // end if
1897
1898   if ( hProcess        != NULL ) CloseHandle          ( hProcess        );
1899   if ( pTkOwner        != NULL ) FreeTokenInformation ( pTkOwner        );
1900   if ( pTkGroups       != NULL ) FreeTokenInformation ( pTkGroups       );
1901   if ( pTkPrimaryGroup != NULL ) FreeTokenInformation ( pTkPrimaryGroup );
1902   if ( pfSD            != NULL ) FreeFileSecurity     ( pfSD            );
1903  
1904  }  // end __finally
1905
1906 #ifdef VAC
1907 leave: ;     // added for VisualAge
1908 #endif
1909
1910  return retVal;
1911  
1912 }  // end _osd_wnt_protection_to_sd */
1913 #endif
1914
1915 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1916 #undef __try
1917 #undef __finally
1918 #undef __leave
1919 #endif
1920
1921 static void __fastcall _test_raise ( HANDLE hFile, Standard_CString str ) {
1922
1923   if (hFile == INVALID_HANDLE_VALUE) {
1924     TCollection_AsciiString buff = "OSD_File :: ";
1925     buff += str;
1926     buff += " (): wrong access";
1927
1928     Standard_ProgramError::Raise(buff.ToCString());
1929   }  // end if
1930
1931 }  // end _test_raise
1932
1933 // Returns number of bytes in the string (including end \n, but excluding \r);
1934 // 
1935 static Standard_Integer __fastcall _get_line (Standard_PCharacter& buffer, DWORD dwBuffSize, LONG& theSeekPos)
1936 {
1937
1938  Standard_PCharacter ptr;
1939
1940  buffer[ dwBuffSize ] = 0;
1941  ptr                  = buffer;
1942
1943  while ( *ptr != 0 ) {
1944  
1945   if (  *ptr == '\n'  )
1946   {
1947     ptr++ ;   // jump newline char.
1948     *ptr = 0 ;
1949     theSeekPos = (LONG)(ptr - buffer - dwBuffSize);
1950     return (Standard_Integer)(ptr - buffer);  
1951   }
1952   else if (  *ptr == '\r' && ptr[ 1 ] == '\n'  )
1953   {
1954     *(ptr++) = '\n' ; // Substitue carriage return by newline.
1955     *ptr = 0 ;
1956     theSeekPos = (LONG)(ptr + 1 - buffer - dwBuffSize);
1957     return (Standard_Integer)(ptr - buffer);  
1958   } 
1959   else if (  *ptr == '\r' && ptr[ 1 ] == 0  ) {
1960     *ptr = '\n' ; // Substitue carriage return by newline
1961     return -1;
1962   }
1963   ++ptr;
1964   
1965  }  // end while
1966
1967  theSeekPos = 0;
1968  return dwBuffSize;
1969 }  // end _get_line
1970
1971 #ifndef OCCT_UWP
1972 static int __fastcall _get_buffer (
1973                         HANDLE hChannel,
1974                         Standard_PCharacter& buffer, 
1975                                    DWORD dwSize,
1976                         BOOL fPeek, BOOL fSocket
1977                        ) {
1978
1979  int   retVal = -1;
1980  int   flags;
1981  DWORD dwDummy;
1982  DWORD dwBytesRead;
1983
1984  if ( fSocket ) {
1985  
1986   flags = fPeek ? MSG_PEEK : 0;
1987
1988   retVal = recv (  ( SOCKET )hChannel, buffer, ( int )dwSize, flags  );
1989
1990   if ( retVal == SOCKET_ERROR ) retVal = -1;
1991
1992  } else {
1993  
1994   if ( fPeek ) {
1995    
1996    if (  !PeekNamedPipe (
1997            hChannel, buffer, dwSize, &dwBytesRead, &dwDummy, &dwDummy
1998           ) && GetLastError () != ERROR_BROKEN_PIPE
1999    )
2000
2001     retVal = -1;
2002
2003    else
2004
2005     retVal = ( int )dwBytesRead;
2006    
2007   } else {
2008
2009    if (  !ReadFile ( hChannel, buffer, dwSize, &dwBytesRead, NULL )  )
2010        
2011     retVal = -1;
2012
2013    else
2014
2015     retVal = ( int )dwBytesRead;
2016    
2017   }  // end else
2018  
2019  }  // end else
2020
2021  return retVal;
2022
2023 }  // end _get_buffer
2024
2025
2026 static DWORD __fastcall _get_access_mask ( OSD_SingleProtection prt ) {
2027
2028  DWORD retVal = 0;
2029
2030  switch ( prt ) {
2031  
2032   case OSD_None:
2033
2034    retVal = 0;
2035
2036   break;
2037
2038   case OSD_R:
2039
2040    retVal = FILE_GENERIC_READ;
2041
2042   break;
2043
2044   case OSD_W:
2045
2046    retVal = FILE_GENERIC_WRITE;
2047
2048   break;
2049
2050   case OSD_RW:
2051
2052    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
2053
2054   break;
2055
2056   case OSD_X:
2057
2058    retVal = FILE_GENERIC_EXECUTE;
2059
2060   break;
2061
2062   case OSD_RX:
2063
2064    retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
2065
2066   break;
2067
2068   case OSD_WX:
2069
2070    retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2071
2072   break;
2073
2074   case OSD_RWX:
2075
2076    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2077
2078   break;
2079
2080   case OSD_D:
2081
2082    retVal = DELETE;
2083
2084   break;
2085
2086   case OSD_RD:
2087
2088    retVal = FILE_GENERIC_READ | DELETE;
2089
2090   break;
2091
2092   case OSD_WD:
2093
2094    retVal = FILE_GENERIC_WRITE | DELETE;
2095
2096   break;
2097
2098   case OSD_RWD:
2099
2100    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
2101
2102   break;
2103
2104   case OSD_XD:
2105
2106    retVal = FILE_GENERIC_EXECUTE | DELETE;
2107
2108   break;
2109
2110   case OSD_RXD:
2111
2112    retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE;
2113
2114   break;
2115
2116   case OSD_WXD:
2117
2118    retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2119
2120   break;
2121
2122   case OSD_RWXD:
2123
2124    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2125
2126   break;
2127
2128   default:
2129
2130    RAISE(  "_get_access_mask (): incorrect parameter"  );
2131  
2132  }  // end switch
2133
2134  return retVal;
2135
2136 }  // end _get_access_mask
2137
2138 static DWORD __fastcall _get_dir_access_mask ( OSD_SingleProtection prt ) {
2139
2140  DWORD retVal = 0;
2141
2142  switch ( prt ) {
2143  
2144   case OSD_None:
2145
2146    retVal = 0;
2147
2148   break;
2149
2150   case OSD_R:
2151
2152    retVal = GENERIC_READ;
2153
2154   break;
2155
2156   case OSD_W:
2157
2158    retVal = GENERIC_WRITE;
2159
2160   break;
2161
2162   case OSD_RW:
2163
2164    retVal = GENERIC_READ | GENERIC_WRITE;
2165
2166   break;
2167
2168   case OSD_X:
2169
2170    retVal = GENERIC_EXECUTE;
2171
2172   break;
2173
2174   case OSD_RX:
2175
2176    retVal = GENERIC_READ | GENERIC_EXECUTE;
2177
2178   break;
2179
2180   case OSD_WX:
2181
2182    retVal = GENERIC_WRITE | GENERIC_EXECUTE;
2183
2184   break;
2185
2186   case OSD_RWX:
2187
2188    retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE;
2189
2190   break;
2191
2192   case OSD_D:
2193
2194    retVal = DELETE;
2195
2196   break;
2197
2198   case OSD_RD:
2199
2200    retVal = GENERIC_READ | DELETE;
2201
2202   break;
2203
2204   case OSD_WD:
2205
2206    retVal = GENERIC_WRITE | DELETE;
2207
2208   break;
2209
2210   case OSD_RWD:
2211
2212    retVal = GENERIC_READ | GENERIC_WRITE | DELETE;
2213
2214   break;
2215
2216   case OSD_XD:
2217
2218    retVal = GENERIC_EXECUTE | DELETE;
2219
2220   break;
2221
2222   case OSD_RXD:
2223
2224    retVal = GENERIC_READ | GENERIC_EXECUTE | DELETE;
2225
2226   break;
2227
2228   case OSD_WXD:
2229
2230    retVal = GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2231
2232   break;
2233
2234   case OSD_RWXD:
2235
2236    retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2237
2238   break;
2239
2240   default:
2241
2242    RAISE(  "_get_dir_access_mask (): incorrect parameter"  );
2243  
2244  }  // end switch
2245
2246  return retVal;
2247
2248 }  // end _get_dir_access_mask
2249 #endif
2250 static HANDLE __fastcall _open_file (
2251                           Standard_CString fName,
2252                           OSD_OpenMode oMode,
2253                           DWORD dwOptions, LPBOOL fNew
2254                          ) {
2255
2256  HANDLE retVal = INVALID_HANDLE_VALUE;
2257  DWORD  dwDesiredAccess = 0;
2258  DWORD  dwCreationDistribution;
2259
2260  switch ( oMode ) {
2261   
2262   case OSD_ReadOnly:
2263
2264    dwDesiredAccess = GENERIC_READ;
2265
2266   break;
2267
2268   case OSD_WriteOnly:
2269
2270    dwDesiredAccess = GENERIC_WRITE;
2271
2272   break;
2273
2274   case OSD_ReadWrite:
2275
2276    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
2277
2278   break;
2279
2280   default:
2281
2282    RAISE(  "_open_file (): incorrect parameter"  );
2283   
2284  }  // end switch
2285
2286  dwCreationDistribution = ( dwOptions != OPEN_NEW ) ? OPEN_EXISTING : CREATE_ALWAYS;
2287
2288  // make wide character string from UTF-8
2289  TCollection_ExtendedString fNameW(fName, Standard_True);
2290 #ifndef OCCT_UWP
2291  retVal = CreateFileW (
2292            fNameW.ToWideString(), dwDesiredAccess,
2293            FILE_SHARE_READ | FILE_SHARE_WRITE,
2294            NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2295           );
2296 #else
2297  CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams = {};
2298  pCreateExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
2299  pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
2300  pCreateExParams.lpSecurityAttributes = NULL;
2301  pCreateExParams.hTemplateFile = NULL;
2302  retVal = CreateFile2 (
2303            fNameW.ToWideString(), dwDesiredAccess,
2304            FILE_SHARE_READ | FILE_SHARE_WRITE,
2305            dwCreationDistribution, &pCreateExParams
2306           );
2307 #endif
2308  if ( retVal          == INVALID_HANDLE_VALUE &&
2309       dwOptions       == OPEN_APPEND          &&
2310       GetLastError () == ERROR_FILE_NOT_FOUND
2311  ) {
2312
2313  
2314   dwCreationDistribution = CREATE_ALWAYS;
2315 #ifndef OCCT_UWP
2316   retVal = CreateFileW (
2317             fNameW.ToWideString(), dwDesiredAccess,
2318             FILE_SHARE_READ | FILE_SHARE_WRITE,
2319             NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2320            );
2321 #else
2322   CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams2 = {};
2323   pCreateExParams2.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
2324   pCreateExParams2.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
2325   pCreateExParams2.lpSecurityAttributes = NULL;
2326   pCreateExParams2.hTemplateFile = NULL;
2327   retVal = CreateFile2(
2328     fNameW.ToWideString(), dwDesiredAccess,
2329     FILE_SHARE_READ | FILE_SHARE_WRITE,
2330     dwCreationDistribution, &pCreateExParams2
2331   );
2332 #endif
2333
2334   *fNew = TRUE;
2335
2336  }  // end if
2337
2338  return retVal;
2339
2340 }  // end _open_file
2341
2342 Standard_Integer __fastcall _get_file_type (
2343                              Standard_CString fName, HANDLE fileHandle
2344                             ) {
2345
2346  Standard_Integer retVal = 0;
2347  int              fileType;
2348
2349  fileType = (fileHandle == INVALID_HANDLE_VALUE ? 
2350              FILE_TYPE_DISK : GetFileType (fileHandle));
2351
2352  switch ( fileType ) {
2353  
2354   case FILE_TYPE_UNKNOWN:
2355
2356    retVal = FLAG_SOCKET;
2357
2358   break;
2359
2360   case FILE_TYPE_DISK:
2361   {
2362    // make wide character string from UTF-8
2363    TCollection_ExtendedString fNameW(fName, Standard_True);
2364
2365    WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
2366    if (GetFileAttributesExW (fNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
2367
2368     retVal = aFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FLAG_DIRECTORY : FLAG_FILE;
2369
2370    else
2371
2372     retVal = 0x80000000;
2373   }
2374   break;
2375
2376   case FILE_TYPE_CHAR:
2377
2378    retVal = FLAG_DEVICE;
2379
2380   break;
2381
2382   case FILE_TYPE_PIPE:
2383
2384    retVal = FLAG_PIPE;
2385
2386   break;
2387  
2388  }  // end switch
2389
2390  return retVal;
2391
2392 }  // end _get_file_type
2393
2394 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2395 #define __try
2396 #define __finally
2397 #define __leave return retVal
2398 #endif
2399
2400 #ifndef OCCT_UWP
2401 // None of the existing security APIs are supported in a UWP applications
2402 BOOL __fastcall _osd_wnt_sd_to_protection (
2403                  PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL fDir
2404                 ) {
2405
2406  int           i;
2407  BOOL          fPresent;
2408  BOOL          fDefaulted;
2409  PACL          pACL;
2410  PSID          pSIDowner;
2411  PSID          pSIDadmin;
2412  PSID          pSIDworld;
2413  LPVOID        pACE;
2414  DWORD         dwAccessOwner = 0;
2415  DWORD         dwAccessGroup = 0;
2416  DWORD         dwAccessAdmin = 0;
2417  DWORD         dwAccessWorld = 0;
2418  BOOL          retVal = FALSE;
2419  GET_PROT_FUNC _get_prot_func = fDir ? &_get_protection_dir : &_get_protection;
2420
2421  __try {
2422
2423   if (  !GetSecurityDescriptorOwner ( pSD, &pSIDowner, &fDefaulted )  ) __leave;
2424
2425   if (  !GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDefaulted ) ||
2426         !fPresent
2427   ) __leave;
2428
2429   if ( pSIDowner == NULL || pACL == NULL ) {
2430   
2431    SetLastError ( ERROR_NO_SECURITY_ON_OBJECT );
2432    __leave;
2433   
2434   }  // end if
2435  
2436   pSIDadmin = AdminSid ();
2437   pSIDworld = WorldSid ();
2438
2439   for ( i = 0; i < ( int )pACL -> AceCount; ++i ) {
2440   
2441    if (  GetAce ( pACL, i, &pACE )  ) {
2442    
2443     if (   EqualSid (  pSIDowner, GET_SID( pACE )  )   )
2444
2445      dwAccessOwner = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2446                      0 : *GET_MSK( pACE );
2447
2448     else if (   EqualSid (  pSIDadmin, GET_SID( pACE )  )   )
2449
2450      dwAccessAdmin = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2451                      0 : *GET_MSK( pACE );
2452
2453     else if (   EqualSid (  pSIDworld, GET_SID( pACE )  )   )
2454
2455      dwAccessWorld = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2456                      0 : *GET_MSK( pACE );
2457
2458     else
2459
2460      dwAccessGroup = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2461                      0 : *GET_MSK( pACE );
2462    
2463    }  // end if
2464   
2465   }  // end for
2466
2467   prot.SetValues (
2468         ( *_get_prot_func ) ( dwAccessAdmin ),
2469         ( *_get_prot_func ) ( dwAccessOwner ),
2470         ( *_get_prot_func ) ( dwAccessGroup ),
2471         ( *_get_prot_func ) ( dwAccessWorld )
2472        );
2473
2474   retVal = TRUE;
2475   
2476  }  // end __try
2477
2478  __finally {}
2479        
2480 #ifdef VAC
2481 leave: ;      // added for VisualAge
2482 #endif
2483
2484  return retVal;
2485
2486 }  // end _osd_wnt_sd_to_protection
2487 #endif
2488
2489 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2490 #undef __try
2491 #undef __finally
2492 #undef __leave
2493 #endif
2494 #ifndef OCCT_UWP
2495 static OSD_SingleProtection __fastcall _get_protection ( DWORD mask ) {
2496
2497  OSD_SingleProtection retVal;
2498
2499  switch ( mask ) {
2500  
2501   case FILE_GENERIC_READ:
2502
2503    retVal = OSD_R;
2504
2505   break;
2506
2507   case FILE_GENERIC_WRITE:
2508
2509    retVal = OSD_W;
2510
2511   break;
2512
2513   case FILE_GENERIC_READ | FILE_GENERIC_WRITE:
2514
2515    retVal = OSD_RW;
2516
2517   break;
2518
2519   case FILE_GENERIC_EXECUTE:
2520
2521    retVal = OSD_X;
2522
2523   break;
2524
2525   case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE:
2526
2527    retVal = OSD_RX;
2528
2529   break;
2530
2531   case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2532
2533    retVal = OSD_WX;
2534
2535   break;
2536
2537   case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2538
2539    retVal = OSD_RWX;
2540
2541   break;
2542
2543   case DELETE:
2544
2545    retVal = OSD_D;
2546
2547   break;
2548
2549   case FILE_GENERIC_READ | DELETE:
2550
2551    retVal = OSD_RD;
2552
2553   break;
2554
2555   case FILE_GENERIC_WRITE | DELETE:
2556
2557    retVal = OSD_WD;
2558
2559   break;
2560
2561   case FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE:
2562
2563    retVal = OSD_RWD;
2564
2565   break;
2566
2567   case FILE_GENERIC_EXECUTE | DELETE:
2568
2569    retVal = OSD_XD;
2570
2571   break;
2572
2573   case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE:
2574
2575    retVal = OSD_RXD;
2576
2577   break;
2578
2579   case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2580
2581    retVal = OSD_WXD;
2582
2583   break;
2584
2585   case FILE_ALL_ACCESS:
2586   case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2587
2588    retVal = OSD_RWXD;
2589
2590   break;
2591
2592   case 0:
2593   default:
2594
2595    retVal = OSD_None;
2596  
2597  }  // end switch
2598
2599  return retVal;
2600
2601 }  // end _get_protection
2602
2603 static OSD_SingleProtection __fastcall _get_protection_dir ( DWORD mask ) {
2604
2605  OSD_SingleProtection retVal;
2606
2607  switch ( mask ) {
2608  
2609   case GENERIC_READ:
2610
2611    retVal = OSD_R;
2612
2613   break;
2614
2615   case GENERIC_WRITE:
2616
2617    retVal = OSD_W;
2618
2619   break;
2620
2621   case GENERIC_READ | GENERIC_WRITE:
2622
2623    retVal = OSD_RW;
2624
2625   break;
2626
2627   case GENERIC_EXECUTE:
2628
2629    retVal = OSD_X;
2630
2631   break;
2632
2633   case GENERIC_READ | GENERIC_EXECUTE:
2634
2635    retVal = OSD_RX;
2636
2637   break;
2638
2639   case GENERIC_WRITE | GENERIC_EXECUTE:
2640
2641    retVal = OSD_WX;
2642
2643   break;
2644
2645   case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE:
2646
2647    retVal = OSD_RWX;
2648
2649   break;
2650
2651   case DELETE:
2652
2653    retVal = OSD_D;
2654
2655   break;
2656
2657   case GENERIC_READ | DELETE:
2658
2659    retVal = OSD_RD;
2660
2661   break;
2662
2663   case GENERIC_WRITE | DELETE:
2664
2665    retVal = OSD_WD;
2666
2667   break;
2668
2669   case GENERIC_READ | GENERIC_WRITE | DELETE:
2670
2671    retVal = OSD_RWD;
2672
2673   break;
2674
2675   case GENERIC_EXECUTE | DELETE:
2676
2677    retVal = OSD_XD;
2678
2679   break;
2680
2681   case GENERIC_READ | GENERIC_EXECUTE | DELETE:
2682
2683    retVal = OSD_RXD;
2684
2685   break;
2686
2687   case GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2688
2689    retVal = OSD_WXD;
2690
2691   break;
2692
2693   case FILE_ALL_ACCESS:
2694   case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2695
2696    retVal = OSD_RWXD;
2697
2698   break;
2699
2700   case 0:
2701   default:
2702
2703    retVal = OSD_None;
2704  
2705  }  // end switch
2706
2707  return retVal;
2708
2709 }  // end _get_protection_dir
2710 #endif
2711
2712 Standard_Boolean OSD_File::IsReadable()
2713 {
2714   TCollection_AsciiString FileName ;
2715   HANDLE Channel ;
2716
2717   myPath.SystemName(FileName) ;
2718   Channel = _open_file(FileName.ToCString(), OSD_ReadOnly, OPEN_OLD) ;
2719   if (Channel == INVALID_HANDLE_VALUE)
2720     return Standard_False ;
2721   else {
2722     CloseHandle (Channel) ;
2723     return Standard_True ;
2724   }
2725 }
2726
2727
2728 Standard_Boolean OSD_File::IsWriteable()
2729 {
2730   TCollection_AsciiString FileName ;
2731   HANDLE Channel ;
2732
2733   myPath.SystemName(FileName) ;
2734   Channel = _open_file(FileName.ToCString(), OSD_ReadWrite, OPEN_OLD) ;
2735   if (Channel == INVALID_HANDLE_VALUE)
2736     return Standard_False ;
2737   else {
2738     CloseHandle (Channel) ;
2739     return Standard_True ;
2740   }
2741 }
2742
2743 Standard_Boolean OSD_File::IsExecutable()
2744 {
2745   return IsReadable() ;
2746
2747 //  if (_access(FileName.ToCString(),0))
2748 }
2749
2750 #endif /* _WIN32 */
2751
2752 // ---------------------------------------------------------------------
2753 // Destructs a file object (unlocks and closes file if it is open)
2754 // ---------------------------------------------------------------------
2755
2756 OSD_File::~OSD_File()
2757 {
2758   if (IsOpen())
2759   {
2760     if (IsLocked())
2761       UnLock();
2762     Close();
2763   }
2764 }
2765
2766 // ---------------------------------------------------------------------
2767 // Read lines in a file while it is increasing.
2768 // Each line is terminated with a <nl>.
2769 // ---------------------------------------------------------------------
2770
2771 #include <OSD.hxx>
2772
2773 Standard_Boolean OSD_File::ReadLastLine(TCollection_AsciiString& aLine,const Standard_Integer aDelay,const Standard_Integer aNbTries)
2774 {
2775   static Standard_Integer MaxLength = 1000 ;
2776   Standard_Integer Len ;
2777   Standard_Integer Count = aNbTries ;
2778
2779   if (Count <= 0)
2780       return Standard_False ;
2781   for(;;) {
2782     ReadLine(aLine, MaxLength, Len) ;
2783     if (!aLine.IsEmpty()) 
2784       return Standard_True ;
2785     if (!--Count)
2786       return Standard_False ;
2787     OSD::SecSleep(aDelay) ;
2788   }
2789 }
2790
2791
2792 Standard_Boolean OSD_File::Edit()
2793 {
2794   cout << "Function OSD_File::Edit() not yet implemented." << endl;
2795   return Standard_False ;
2796 }
2797
2798
2799