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