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