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