0020716: Eliminate usage of "config.h" header file
[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
832 #ifndef _INC_TCHAR
833 # include <tchar.h>
834 #endif  // _INC_TCHAR
835
836 #if defined(__CYGWIN32__) || defined(__MINGW32__)
837 #define VAC
838 #define _int64 int
839 #endif
840
841 #pragma comment( lib, "WSOCK32.LIB"  )
842 #pragma comment( lib, "WINSPOOL.LIB" )
843
844 #define ACE_HEADER_SIZE (  sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD )  )
845
846 #define RAISE( arg ) Standard_ProgramError :: Raise (  ( arg )  )
847 #define TEST_RAISE( arg ) _test_raise (  myFileHandle, ( arg )  )
848
849 #define OPEN_NEW    0
850 #define OPEN_OLD    1
851 #define OPEN_APPEND 2
852
853 void                            _osd_wnt_set_error        ( OSD_Error&, OSD_WhoAmI, ... );
854 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, char* = NULL );
855 BOOL                 __fastcall _osd_wnt_sd_to_protection (
856                                  PSECURITY_DESCRIPTOR, OSD_Protection&, BOOL
857                                 );
858 BOOL                 __fastcall _osd_print (const Standard_PCharacter, Standard_CString );
859
860 static void      __fastcall _test_raise ( HANDLE, Standard_CString );
861 static DWORDLONG __fastcall _get_line   ( Standard_PCharacter&, DWORD );
862 static int       __fastcall _get_buffer ( HANDLE, Standard_PCharacter&, DWORD, BOOL, BOOL );
863 static DWORD     __fastcall _get_access_mask ( OSD_SingleProtection );
864 static DWORD     __fastcall _get_dir_access_mask ( OSD_SingleProtection prt );
865 static HANDLE    __fastcall _open_file  ( Standard_CString, OSD_OpenMode, DWORD, LPBOOL = NULL );
866
867 static OSD_SingleProtection __fastcall _get_protection     ( DWORD );
868 static OSD_SingleProtection __fastcall _get_protection_dir ( DWORD );
869
870 typedef OSD_SingleProtection ( __fastcall *GET_PROT_FUNC ) ( DWORD );
871
872 Standard_Integer __fastcall _get_file_type ( Standard_CString, HANDLE );
873
874 // ---------------------------------------------------------------------
875 // Create an empty file object
876 // ---------------------------------------------------------------------
877
878 OSD_File :: OSD_File ()
879 {
880  ImperativeFlag = Standard_False;
881  myLock         = OSD_NoLock;
882  myIO           = 0;
883  myFileChannel  = -1;
884  myFileHandle   = INVALID_HANDLE_VALUE;
885 }  // end constructor ( 1 )
886
887 // ---------------------------------------------------------------------
888 // Create and initialize a file object
889 // ---------------------------------------------------------------------
890
891 OSD_File :: OSD_File ( const OSD_Path& Name ) : OSD_FileNode ( Name )
892 {
893  ImperativeFlag = Standard_False;
894  myLock         = OSD_NoLock;
895  myIO           = 0;
896  myPath         = Name;
897  myFileChannel  = -1;
898  myFileHandle   = INVALID_HANDLE_VALUE;
899 }  // end constructor ( 2 )
900
901 // protect against occasional use of myFileHande in Windows code
902 #define myFileChannel myFileChannel_is_only_for_Linux
903
904 // ---------------------------------------------------------------------
905 // Build a file if it doesn't exist or create again if it already exists
906 // ---------------------------------------------------------------------
907
908 void OSD_File :: Build (
909                   const OSD_OpenMode Mode, const OSD_Protection& Protect
910                  ) {
911
912  TCollection_AsciiString fName;
913
914  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
915    Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
916  }
917                                         
918  if (myFileHandle != INVALID_HANDLE_VALUE)
919
920   RAISE(  TEXT( "OSD_File :: Build (): incorrect call - file already opened" )  );
921
922  myMode = Mode;
923  myPath.SystemName ( fName );
924
925  if (  fName.IsEmpty ()  )
926
927   RAISE(  TEXT( "OSD_File :: Build (): incorrent call - no filename given" )  );
928
929  myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_NEW );
930
931  if (myFileHandle == INVALID_HANDLE_VALUE)
932
933   _osd_wnt_set_error ( myError, OSD_WFile );
934
935  else {
936
937   SetProtection ( Protect );
938   myIO |= FLAG_FILE;
939
940  }  // end else
941
942 }  // end OSD_File :: Build
943
944
945
946 // ---------------------------------------------------------------------
947 // Open a file
948 // ---------------------------------------------------------------------
949
950 void OSD_File :: Open (const OSD_OpenMode Mode, const OSD_Protection& /*Protect*/)
951 {
952
953  TCollection_AsciiString fName;
954
955
956  if (myFileHandle != INVALID_HANDLE_VALUE)
957
958   RAISE(  TEXT( "OSD_File :: Open (): incorrect call - file already opened" )  );
959
960  myMode = Mode;
961  myPath.SystemName ( fName );
962
963  if (  fName.IsEmpty ()  )
964
965   RAISE(  TEXT( "OSD_File :: Open (): incorrent call - no filename given" )  );
966
967  myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_OLD );
968
969  if (myFileHandle == INVALID_HANDLE_VALUE) {
970
971    _osd_wnt_set_error ( myError, OSD_WFile );
972  }
973  else
974    {
975      myIO |= _get_file_type (  fName.ToCString (), myFileHandle  );
976    }
977 }  // end OSD_File :: Open
978
979 // ---------------------------------------------------------------------
980 // Append to an existing file
981 // ---------------------------------------------------------------------
982
983 void OSD_File :: Append (
984                   const OSD_OpenMode Mode, const OSD_Protection& Protect
985                  ) {
986
987  BOOL                    fNew = FALSE;
988  TCollection_AsciiString fName;
989
990  if (myFileHandle != INVALID_HANDLE_VALUE)
991
992   RAISE(  TEXT( "OSD_File :: Append (): incorrect call - file already opened" )  );
993
994  myMode = Mode;
995  myPath.SystemName ( fName );
996
997  if (  fName.IsEmpty ()  )
998
999   RAISE(  TEXT( "OSD_File :: Append (): incorrent call - no filename given" )  );
1000
1001  myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_APPEND, &fNew );
1002
1003  if (myFileHandle == INVALID_HANDLE_VALUE)
1004
1005   _osd_wnt_set_error ( myError, OSD_WFile );
1006
1007  else {
1008
1009   if ( !fNew ) {
1010
1011    myIO |= _get_file_type (  fName.ToCString (), myFileHandle  );
1012    Seek ( 0, OSD_FromEnd );
1013
1014   } else {
1015   
1016    SetProtection ( Protect );
1017    myIO |= FLAG_FILE;
1018   
1019   }  // end else
1020
1021  }  // end else;
1022
1023 }  // end OSD_File :: Append
1024
1025 // ---------------------------------------------------------------------
1026 // Read content of a file
1027 // ---------------------------------------------------------------------
1028  
1029 void OSD_File :: Read (
1030                   TCollection_AsciiString& Buffer, const Standard_Integer Nbyte
1031                  ) {
1032
1033  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
1034    cout << " OSD_File::Read : it is a directory " << endl;
1035    return ;
1036 //   Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1037  }
1038                                         
1039  Standard_Integer NbyteRead;
1040  Standard_Address buff;
1041
1042  TEST_RAISE(  TEXT( "Read" )  );
1043      
1044  buff = ( Standard_Address )new Standard_Character[ Nbyte + 1 ];
1045
1046  Read ( buff, Nbyte, NbyteRead );
1047
1048  (  ( Standard_PCharacter )buff  )[ NbyteRead ] = 0;
1049
1050  if ( NbyteRead != 0 )
1051
1052   Buffer = ( Standard_PCharacter )buff;
1053
1054  else
1055
1056   Buffer.Clear ();
1057
1058  delete [] buff;
1059
1060 }  // end OSD_File :: Read
1061
1062 // ---------------------------------------------------------------------
1063 // Read a line from a file
1064 // ---------------------------------------------------------------------
1065
1066 // Modified so that we have <nl> at end of line if we have read <nl> or <cr>
1067 // in the file.
1068 // by LD 17 dec 98 for B4.4
1069
1070 void OSD_File :: ReadLine (
1071                   TCollection_AsciiString& Buffer,
1072                   const Standard_Integer NByte, Standard_Integer& NbyteRead
1073                  ) {
1074
1075  DWORDLONG          status;
1076  DWORD              dwBytesRead;
1077  DWORD              dwDummy;
1078  Standard_Character peekChar;
1079  Standard_PCharacter ppeekChar;
1080  Standard_PCharacter cBuffer;
1081  Standard_CString   eos;
1082  DWORD              dwSeekPos;
1083
1084  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
1085    Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1086  }
1087                                         
1088  TEST_RAISE(  TEXT( "ReadLine" )  );              
1089
1090  if (  myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE )  )
1091
1092   RAISE(  TEXT( "OSD_File :: ReadLine (): attempt to read from write only pipe" )  );
1093
1094                                         // +----> leave space for end-of-string
1095                                         // |       plus <CR><LF> sequence      
1096                                         // |
1097
1098  ppeekChar=&peekChar;
1099  cBuffer = new Standard_Character[ NByte + 3 ];
1100
1101  if ( myIO & FLAG_FILE ) {
1102  
1103   if (!ReadFile (myFileHandle, cBuffer, (DWORD)NByte, &dwBytesRead, NULL)) {  // an error occured
1104
1105    _osd_wnt_set_error ( myError, OSD_WFile );   
1106    Buffer.Clear ();
1107    NbyteRead = 0;
1108    
1109   } else if ( dwBytesRead == 0 ) {  // end-of-file reached
1110    
1111    Buffer.Clear ();
1112    NbyteRead = 0;
1113    myIO |= FLAG_EOF;
1114    
1115   } else {
1116    myIO &= ~FLAG_EOF ;  // if the file increased since last read (LD)
1117    status = _get_line ( cBuffer, dwBytesRead );
1118
1119    dwSeekPos = LODWORD( status );
1120    eos       = ( Standard_CString )HIDWORD( status );
1121 #ifdef VAC
1122    if ( (__int64) status == (__int64) -1 ) {  // last character in the buffer is <CR> -
1123 #else
1124    if ( status == 0xFFFFFFFFFFFFFFFF ) {  // last character in the buffer is <CR> -
1125                                           // peek next character to see if it is a <LF>
1126 #endif
1127     if (!ReadFile (myFileHandle, ppeekChar, 1, &dwDummy, NULL)) {
1128     
1129      _osd_wnt_set_error ( myError, OSD_WFile );
1130
1131     } else if ( dwDummy != 0 ) {  // end-of-file reached ?
1132
1133      if ( peekChar != '\n' )  // if we did not get a <CR><LF> sequence
1134     
1135      // adjust file position
1136
1137       SetFilePointer (myFileHandle, -1, NULL, FILE_CURRENT);
1138
1139     } else
1140      myIO |= FLAG_EOF;
1141
1142     NbyteRead = dwBytesRead;
1143
1144    } else {
1145
1146     if ( dwSeekPos != 0 )
1147      SetFilePointer (myFileHandle, (LONG)dwSeekPos, NULL, FILE_CURRENT);
1148
1149     NbyteRead = ( Standard_Integer )( eos - cBuffer );
1150
1151    }
1152
1153   }  // end else
1154    
1155  } else if ( myIO & FLAG_SOCKET || myIO & FLAG_PIPE || myIO & FLAG_NAMED_PIPE ) {
1156
1157   dwBytesRead = (DWORD)_get_buffer (myFileHandle, cBuffer, 
1158                                     (DWORD)NByte, TRUE, myIO & FLAG_SOCKET);
1159
1160   if (  ( int )dwBytesRead == -1  ) { // an error occured
1161
1162    _osd_wnt_set_error ( myError, OSD_WFile );
1163    Buffer.Clear ();
1164    NbyteRead = 0;
1165
1166   } else if ( dwBytesRead == 0 )  { // connection closed - set end-of-file flag
1167
1168    Buffer.Clear ();
1169    NbyteRead = 0;
1170    myIO |= FLAG_EOF;
1171
1172   } else {
1173
1174    status = _get_line ( cBuffer, dwBytesRead );
1175
1176    dwSeekPos = LODWORD( status );
1177    eos       = ( Standard_CString )HIDWORD( status );
1178
1179 #ifdef VAC
1180    if ( (__int64) status == (__int64) -1 ) {  // last character in the buffer is <CR> -
1181 #else  
1182    if ( status == 0xFFFFFFFFFFFFFFFF ) {  // last character in the buffer is <CR> -    
1183                                           // peek next character to see if it is a <LF>
1184 #endif
1185
1186     NbyteRead = dwBytesRead; // (LD) always fits this case.
1187
1188     dwDummy = _get_buffer (myFileHandle, ppeekChar, 1, TRUE, myIO & FLAG_SOCKET);
1189     if (  ( int )dwDummy == -1  ) {  // an error occured
1190    
1191      _osd_wnt_set_error ( myError, OSD_WFile );
1192
1193     } else if ( dwDummy != 0 ) {  // connection closed ?
1194
1195      if ( peekChar == '\n' )  // we got a <CR><LF> sequence
1196
1197        dwBytesRead++ ;  // (LD) we have to jump <LF>
1198     } else
1199
1200      myIO |= FLAG_EOF;
1201
1202    } else {
1203
1204     if ( dwSeekPos != 0 )
1205      dwBytesRead = dwBytesRead + dwSeekPos;
1206
1207     NbyteRead  = ( Standard_Integer )( eos - cBuffer );
1208
1209    }
1210
1211    // Don't rewrite datas in cBuffer.
1212
1213    Standard_PCharacter cDummyBuffer = new Standard_Character[ NByte + 3 ];
1214
1215    // remove pending input
1216    _get_buffer (myFileHandle, cDummyBuffer, dwBytesRead, FALSE, myIO & FLAG_SOCKET);
1217    delete [] cDummyBuffer ;
1218
1219   }  // end else
1220    
1221  } else
1222
1223   RAISE(  TEXT( "OSD_File :: ReadLine (): incorrect call - file is a directory" )  );
1224
1225  if (  !Failed () && !IsAtEnd ()  )
1226
1227   Buffer = cBuffer;
1228
1229  delete [] (Standard_PCharacter)cBuffer;
1230
1231 }  // end OSD_File :: ReadLine
1232
1233 // -------------------------------------------------------------------------- 
1234 // Read content of a file
1235 // -------------------------------------------------------------------------- 
1236
1237 void OSD_File :: Read (
1238                   Standard_Address& Buffer,
1239                   const Standard_Integer Nbyte, Standard_Integer& Readbyte
1240                  ) {
1241
1242  DWORD dwBytesRead;
1243
1244  if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) { 
1245    Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1246  }
1247                                         
1248  TEST_RAISE(  TEXT( "Read" )  );
1249
1250  if (  myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE )  )
1251
1252   RAISE(  TEXT( "OSD_File :: Read (): attempt to read from write only pipe" )  );
1253
1254  if (!ReadFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesRead, NULL)) {
1255  
1256   _osd_wnt_set_error ( myError, OSD_WFile );
1257   dwBytesRead = 0;
1258  
1259  } else if ( dwBytesRead == 0 )
1260
1261   myIO |= FLAG_EOF;
1262
1263  else
1264
1265   myIO &= ~FLAG_EOF;
1266
1267  Readbyte = ( Standard_Integer )dwBytesRead;
1268
1269 }  // end OSD_File :: Read
1270
1271 void OSD_File :: Write (
1272                   const TCollection_AsciiString& Buffer,
1273                   const Standard_Integer Nbyte
1274                  ) {
1275
1276  Write (  ( Standard_Address )Buffer.ToCString (), Nbyte  );
1277
1278 }  // end OSD_File :: Write
1279
1280 // -------------------------------------------------------------------------- 
1281 // Write content of a file
1282 // -------------------------------------------------------------------------- 
1283
1284 void OSD_File :: Write (
1285                   const Standard_Address Buffer,
1286                   const Standard_Integer Nbyte
1287                  ) {
1288
1289  DWORD dwBytesWritten;
1290
1291  TEST_RAISE(  TEXT( "Write" )  );
1292
1293  if ( myIO & FLAG_PIPE && myIO & FLAG_READ_PIPE )
1294
1295   RAISE(  TEXT( "OSD_File :: Write (): attempt to write to read only pipe" )  );
1296
1297  if (!WriteFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesWritten, NULL) || 
1298      dwBytesWritten != (DWORD)Nbyte)
1299
1300   _osd_wnt_set_error ( myError, OSD_WFile );
1301
1302 }  // end OSD_File :: Write
1303
1304 void OSD_File :: Seek (
1305                   const Standard_Integer Offset, const OSD_FromWhere Whence
1306                  ) {
1307
1308  DWORD dwMoveMethod = 0;
1309
1310  TEST_RAISE(  TEXT( "Seek" )  );
1311
1312  if ( myIO & FLAG_FILE || myIO & FLAG_DIRECTORY ) {
1313
1314   switch ( Whence ) {
1315   
1316    case OSD_FromBeginning:
1317
1318     dwMoveMethod = FILE_BEGIN;
1319
1320    break;
1321
1322    case OSD_FromHere:
1323
1324     dwMoveMethod = FILE_CURRENT;
1325
1326    break;
1327
1328    case OSD_FromEnd:
1329
1330     dwMoveMethod = FILE_END;
1331
1332    break;
1333
1334    default:
1335
1336     RAISE(  TEXT( "OSD_File :: Seek (): invalid parameter" )  );
1337   
1338   }  // end switch
1339
1340   if (SetFilePointer (myFileHandle, (LONG)Offset, NULL, dwMoveMethod) == 0xFFFFFFFF)
1341
1342    _osd_wnt_set_error ( myError, OSD_WFile );
1343   
1344  }  // end if
1345
1346  myIO &= ~FLAG_EOF;
1347
1348 }  // end OSD_File :: Seek
1349
1350 // -------------------------------------------------------------------------- 
1351 // Close a file
1352 // -------------------------------------------------------------------------- 
1353
1354 void OSD_File :: Close () {
1355
1356  TEST_RAISE(  TEXT( "Close" )  );
1357
1358  CloseHandle (myFileHandle);
1359
1360  myFileHandle = INVALID_HANDLE_VALUE;
1361  myIO          = 0;
1362
1363 }  // end OSD_File :: Close
1364
1365 // -------------------------------------------------------------------------- 
1366 // Test if at end of file
1367 // -------------------------------------------------------------------------- 
1368
1369 Standard_Boolean OSD_File :: IsAtEnd () {
1370
1371  TEST_RAISE(  TEXT( "IsAtEnd" )  );
1372
1373  if (myIO & FLAG_EOF)
1374    return Standard_True ;
1375  return Standard_False ;
1376
1377 }  // end OSD_File :: IsAtEnd
1378
1379 OSD_KindFile OSD_File :: KindOfFile () const {
1380
1381  OSD_KindFile     retVal;
1382  Standard_Integer flags;
1383
1384  if (myFileHandle == INVALID_HANDLE_VALUE) {
1385
1386   TCollection_AsciiString fName;
1387
1388   myPath.SystemName ( fName );
1389
1390   if (  fName.IsEmpty ()  )
1391
1392    RAISE(  TEXT( "OSD_File :: KindOfFile (): incorrent call - no filename given" )  );
1393
1394   flags = _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE);
1395
1396  } else
1397
1398   flags = myIO;
1399
1400  switch ( flags & FLAG_TYPE ) {
1401  
1402   case FLAG_FILE:
1403
1404    retVal = OSD_FILE;
1405
1406   break;
1407
1408   case FLAG_DIRECTORY:
1409
1410    retVal = OSD_DIRECTORY;
1411
1412   break;
1413
1414   case FLAG_SOCKET:
1415
1416    retVal = OSD_SOCKET;
1417
1418   break;
1419
1420   default:
1421
1422    retVal = OSD_UNKNOWN;
1423  
1424  }  // end switch
1425
1426  return retVal;
1427
1428 }  // end OSD_File :: KindOfFile
1429 #define PRO13792
1430 #ifndef PRO13792
1431
1432 OSD_File OSD_File :: BuildTemporary () {
1433
1434  OSD_Protection          prt;
1435  OSD_File                retVal;
1436
1437 #ifdef VAC
1438  char tmpbuf [MAX_PATH];
1439  if (GetTempPath (MAX_PATH, tmpbuf) == 0)
1440  {
1441     perror ("ERROR in GetTempPath");
1442     exit (10);
1443  }
1444  char tmpbuf2 [MAX_PATH];
1445  if (GetTempFileName (tmpbuf, NULL, 0, tmpbuf2) == 0)
1446  {
1447     perror ("ERROR in GetTempFileName");
1448     exit (10);
1449  }
1450  TCollection_AsciiString fileName (  tmpbuf2  );
1451 #else
1452  TCollection_AsciiString fileName (  _ttmpnam ( NULL )  );
1453 #endif
1454
1455  OSD_Path                filePath ( fileName );
1456
1457  retVal.SetPath ( filePath );
1458  retVal.Build   ( OSD_ReadWrite, prt );
1459
1460  return retVal;
1461
1462 }  // end OSD_File :: BuildTemporary
1463
1464 #else   // PRO13792
1465
1466 //-------------------------------------------------debutpri???980424
1467
1468 typedef struct _osd_wnt_key {
1469
1470                 HKEY   hKey;
1471                 LPTSTR keyPath;
1472
1473                } OSD_WNT_KEY;
1474
1475
1476 OSD_File OSD_File :: BuildTemporary () {
1477
1478  OSD_Protection prt;
1479  OSD_File       retVal;
1480  HKEY           hKey;
1481  TCHAR          tmpPath[ MAX_PATH ];
1482  BOOL           fOK = FALSE;
1483  OSD_WNT_KEY    regKey[ 2 ] = {
1484  
1485                  { HKEY_LOCAL_MACHINE,
1486                    TEXT( "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment" )
1487                  },
1488                  { HKEY_USERS,
1489                    TEXT( ".DEFAULT\\Environment" )
1490                  }
1491  
1492                 };
1493  
1494  for ( int i = 0; i < 2; ++i ) {
1495
1496   if (  RegOpenKeyEx (
1497          regKey[ i ].hKey, regKey[ i ].keyPath, 0, KEY_QUERY_VALUE, &hKey
1498        ) == ERROR_SUCCESS
1499   ) {
1500   
1501    DWORD dwType;
1502    DWORD dwSize = 0;
1503
1504    if (  RegQueryValueEx (
1505           hKey, TEXT( "TEMP" ), NULL, &dwType, NULL, &dwSize
1506          ) == ERROR_SUCCESS
1507    ) {
1508   
1509     LPTSTR kVal = ( LPTSTR )HeapAlloc (
1510                              GetProcessHeap (), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
1511                              dwSize + sizeof ( TCHAR )
1512                             );
1513
1514      RegQueryValueEx (  hKey, TEXT( "TEMP" ), NULL, &dwType, ( LPBYTE )kVal, &dwSize  );
1515
1516      if ( dwType == REG_EXPAND_SZ )
1517     
1518       ExpandEnvironmentStrings ( kVal, tmpPath, MAX_PATH );
1519
1520      else
1521
1522       lstrcpy ( tmpPath, kVal );
1523
1524     HeapFree (  GetProcessHeap (), 0, ( LPVOID )kVal  );
1525     fOK = TRUE;
1526
1527    }  // end if
1528
1529    RegCloseKey ( hKey );
1530
1531   }  // end if
1532
1533   if ( fOK ) break;
1534
1535  }  // end for
1536
1537  if ( !fOK ) lstrcpy (  tmpPath, TEXT( "./" )  );
1538  
1539  GetTempFileName ( tmpPath, "CSF", 0, tmpPath );
1540
1541  retVal.SetPath (  OSD_Path ( tmpPath )  );
1542  retVal.Build   (  OSD_ReadWrite, prt    );
1543
1544  return retVal;
1545
1546 }  // end OSD_File :: BuildTemporary
1547
1548 #endif // PRO13792
1549
1550 //-------------------------------------------------finpri???980424
1551
1552 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1553 #define __try
1554 #define __finally
1555 #define __leave return
1556 #endif
1557
1558 void OSD_File :: SetLock ( const OSD_LockType Lock ) {
1559
1560  DWORD      dwFlags;
1561  OVERLAPPED ovlp;
1562
1563  TEST_RAISE(  TEXT( "SetLock" )  );
1564  
1565  ZeroMemory (  &ovlp, sizeof ( OVERLAPPED )  );
1566
1567  __try {
1568
1569   if (  ( myLock = Lock ) == OSD_NoLock  ) {
1570
1571    UnLock ();
1572    __leave;
1573
1574   } else if ( myLock == OSD_ReadLock || myLock == OSD_ExclusiveLock ) {
1575
1576    dwFlags = LOCKFILE_EXCLUSIVE_LOCK;
1577
1578   } else
1579
1580    dwFlags = 0;
1581
1582   LARGE_INTEGER aSize;
1583   aSize.QuadPart = Size();
1584   if (!LockFileEx (myFileHandle, dwFlags, 0, aSize.LowPart, aSize.HighPart, &ovlp)) {
1585
1586    _osd_wnt_set_error ( myError, OSD_WFile );
1587    __leave;
1588
1589   }  // end if
1590
1591   ImperativeFlag = Standard_True;
1592
1593  }  // end __try
1594
1595  __finally {}
1596
1597 #ifdef VAC
1598 leave: ;         // added for VisualAge
1599 #endif
1600 }  // end OSD_File :: SetLock
1601
1602 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1603 #undef __try
1604 #undef __finally
1605 #undef __leave
1606 #endif
1607
1608 void OSD_File :: UnLock () {
1609
1610  TEST_RAISE(  TEXT( "Unlock" )  );
1611
1612  if ( ImperativeFlag ) {
1613  
1614   LARGE_INTEGER aSize;
1615   aSize.QuadPart = Size();
1616   if (!UnlockFile (myFileHandle, 0, 0, aSize.LowPart, aSize.HighPart))
1617    
1618    _osd_wnt_set_error ( myError, OSD_WFile );
1619
1620   ImperativeFlag = Standard_False;
1621  
1622  }  // end if
1623
1624 }  // end OSD_File :: UnLock
1625
1626 OSD_LockType OSD_File :: GetLock () {
1627
1628  return myLock;
1629
1630 }  // end OSD_File :: GetLock
1631
1632 Standard_Boolean OSD_File :: IsLocked () {
1633
1634  TEST_RAISE(  TEXT( "IsLocked" )  );
1635
1636  return ImperativeFlag;
1637
1638 }  // end OSD_File :: IsLocked
1639
1640
1641 // -------------------------------------------------------------------------- 
1642 // Return size of a file
1643 // -------------------------------------------------------------------------- 
1644
1645 Standard_Size OSD_File :: Size () {
1646
1647  Standard_Integer retVal;
1648
1649  TEST_RAISE(  TEXT( "Size" )  );
1650
1651  LARGE_INTEGER aSize;
1652  aSize.QuadPart = 0;
1653  retVal = GetFileSizeEx (myFileHandle, &aSize);
1654
1655  if (  retVal == 0  )
1656
1657   _osd_wnt_set_error ( myError, OSD_WFile );
1658
1659  return (Standard_Size)aSize.QuadPart;
1660
1661 }  // end OSD_File :: Size
1662
1663 // -------------------------------------------------------------------------- 
1664 // Print contains of a file
1665 // -------------------------------------------------------------------------- 
1666
1667 void OSD_File :: Print ( const OSD_Printer& WhichPrinter ) {
1668
1669  if (myFileHandle != INVALID_HANDLE_VALUE)
1670
1671   RAISE(  TEXT( "OSD_File :: Print (): incorrect call - file opened" )  );
1672
1673  TCollection_AsciiString pName, fName;
1674
1675  WhichPrinter.Name ( pName );
1676  myPath.SystemName ( fName );
1677
1678  if (   !_osd_print ( (Standard_PCharacter)pName.ToCString (), fName.ToCString ()  )   )
1679
1680   _osd_wnt_set_error ( myError, OSD_WFile );
1681
1682 }  // end OSD_File :: Print
1683
1684 // -------------------------------------------------------------------------- 
1685 // Test if a file is open
1686 // -------------------------------------------------------------------------- 
1687
1688 Standard_Boolean OSD_File :: IsOpen () const {
1689
1690  return myFileHandle != INVALID_HANDLE_VALUE;
1691
1692 }  // end OSD_File :: IsOpen
1693
1694 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1695 #define __try
1696 #define __finally
1697 #define __leave return retVal
1698 #endif
1699
1700 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd (
1701                                  const OSD_Protection& prot, BOOL fDir, char* fName
1702                                 ) {
1703
1704  int                  i, j;
1705  BOOL                 fOK      = FALSE;
1706  PACL                 pACL     = NULL;
1707  HANDLE               hProcess = NULL;
1708  PSID                 pSIDowner;
1709  PSID                 pSIDadmin;
1710  PSID                 pSIDworld;
1711  PSID                 pSIDtemp;
1712  DWORD                dwAccessAdmin;
1713  DWORD                dwAccessGroup;
1714  DWORD                dwAccessOwner;
1715  DWORD                dwAccessWorld;
1716  DWORD                dwAccessAdminDir;
1717  DWORD                dwAccessGroupDir;
1718  DWORD                dwAccessOwnerDir;
1719  DWORD                dwAccessWorldDir;
1720  DWORD                dwACLsize       = sizeof ( ACL );
1721  DWORD                dwIndex         = 0;
1722  PTOKEN_OWNER         pTkOwner        = NULL;
1723  PTOKEN_GROUPS        pTkGroups       = NULL;
1724  PTOKEN_PRIMARY_GROUP pTkPrimaryGroup = NULL;
1725  PSECURITY_DESCRIPTOR retVal = NULL;
1726  PSECURITY_DESCRIPTOR pfSD = NULL;
1727  BOOL                 fDummy;
1728  PFILE_ACE            pFileACE;
1729
1730  __try {
1731
1732   j = fDir ? 1 : 0;
1733
1734   if (  !OpenProcessToken (
1735           GetCurrentProcess (), TOKEN_QUERY, &hProcess
1736          )
1737   ) __leave;
1738
1739   if (   (  pTkGroups = ( PTOKEN_GROUPS )GetTokenInformationEx (
1740                                           hProcess, TokenGroups
1741                                          )
1742          ) == NULL
1743   ) __leave; 
1744   
1745   if (   (  pTkOwner = ( PTOKEN_OWNER )GetTokenInformationEx (
1746                                         hProcess, TokenOwner
1747                                        )
1748          ) == NULL
1749   ) __leave;
1750
1751   if (   (  pTkPrimaryGroup = ( PTOKEN_PRIMARY_GROUP )GetTokenInformationEx (
1752                                                        hProcess, TokenPrimaryGroup
1753                                                       )
1754          ) == NULL
1755   ) __leave;
1756
1757
1758 retry:
1759   if ( fName == NULL )
1760
1761    pSIDowner = pTkOwner -> Owner;
1762
1763   else {
1764
1765    pfSD = GetFileSecurityEx ( fName, OWNER_SECURITY_INFORMATION );
1766
1767    if (  pfSD == NULL || !GetSecurityDescriptorOwner ( pfSD, &pSIDowner, &fDummy )  ) {
1768
1769     fName = NULL;
1770     goto retry;
1771
1772    }  // end if
1773
1774   }  // end else
1775
1776   pSIDadmin = AdminSid ();
1777   pSIDworld = WorldSid ();
1778
1779   dwAccessAdmin = _get_access_mask (  prot.System ()  );
1780   dwAccessGroup = _get_access_mask (  prot.Group  ()  );
1781   dwAccessOwner = _get_access_mask (  prot.User   ()  );
1782   dwAccessWorld = _get_access_mask (  prot.World  ()  );
1783
1784   dwAccessAdminDir = _get_dir_access_mask (  prot.System ()  );
1785   dwAccessGroupDir = _get_dir_access_mask (  prot.Group  ()  );
1786   dwAccessOwnerDir = _get_dir_access_mask (  prot.User   ()  );
1787   dwAccessWorldDir = _get_dir_access_mask (  prot.World  ()  );
1788
1789   if (  dwAccessGroup != 0  ) {
1790                                              
1791    for ( i = 0; i < ( int )pTkGroups -> GroupCount; ++i ) {
1792
1793     pSIDtemp = pTkGroups -> Groups[ i ].Sid;
1794
1795     if (  !NtPredefinedSid ( pSIDtemp                                  ) &&
1796           !EqualSid        ( pSIDtemp, pSIDworld                       ) &&
1797           !EqualSid        ( pSIDtemp, pTkPrimaryGroup -> PrimaryGroup ) &&
1798            IsValidSid      ( pSIDtemp                                  )
1799     )
1800
1801      dwACLsize += ( (  GetLengthSid ( pSIDtemp ) + ACE_HEADER_SIZE  ) << j );
1802
1803    }  // end for
1804   
1805   }  // end if
1806
1807   dwACLsize += (  ( ( GetLengthSid ( pSIDowner ) + ACE_HEADER_SIZE ) << j ) +
1808                   ( ( GetLengthSid ( pSIDadmin ) + ACE_HEADER_SIZE ) << j ) +
1809                   ( ( GetLengthSid ( pSIDworld ) + ACE_HEADER_SIZE ) << j )
1810                );
1811
1812   if (   (  pACL = CreateAcl ( dwACLsize )  ) == NULL   ) __leave;
1813
1814   if ( dwAccessAdmin != 0 )
1815
1816    if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1817                                       dwAccessAdmin, 0,
1818                                       pSIDadmin
1819                                      )
1820            ) != NULL
1821    ) {
1822
1823     AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1824
1825     if ( fDir ) {
1826
1827      pFileACE -> dwMask = dwAccessAdminDir;
1828      pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1829      AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1830
1831     }  // end if
1832
1833     FreeAce ( pFileACE );
1834
1835    }  // end if
1836
1837   if ( dwAccessOwner != 0 )
1838
1839    if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1840                                       dwAccessOwner, 0, pSIDowner
1841                                      )
1842           ) != NULL
1843    ) {
1844
1845     AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1846
1847     if ( fDir ) {
1848
1849      pFileACE -> dwMask = dwAccessOwnerDir;
1850      pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1851      AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1852    
1853     }  // end if
1854
1855     FreeAce ( pFileACE );
1856
1857    }  // end if
1858
1859   if ( dwAccessWorld != 0 )
1860
1861    if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1862                                       dwAccessWorld, 0, pSIDworld
1863                                      )
1864           ) != NULL
1865    ) {
1866
1867     AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1868
1869     if ( fDir ) {
1870
1871      pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1872      AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1873    
1874     }  // end if
1875
1876     FreeAce ( pFileACE );
1877
1878    }  // end if
1879
1880   if ( dwAccessGroup != 0 ) {
1881
1882    for ( i = 0; i < ( int )pTkGroups -> GroupCount; ++i ) {
1883
1884     pSIDtemp = pTkGroups -> Groups[ i ].Sid;
1885
1886     if (  !NtPredefinedSid ( pSIDtemp                                  ) &&
1887           !EqualSid        ( pSIDtemp, pSIDworld                       ) &&
1888           !EqualSid        ( pSIDtemp, pTkPrimaryGroup -> PrimaryGroup ) &&
1889            IsValidSid      ( pSIDtemp                                  )
1890     ) {
1891
1892      if ( dwAccessGroup != 0 )
1893
1894       if (   (  pFileACE = ( PFILE_ACE )AllocAccessAllowedAce (
1895                                          dwAccessGroup, 0, pSIDtemp
1896                                         )
1897              ) != NULL
1898       ) {
1899
1900        AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1901
1902       if ( fDir ) {
1903
1904        pFileACE -> header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1905        AddAce ( pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE -> header.AceSize );
1906    
1907       }  // end if
1908
1909       FreeAce ( pFileACE );
1910
1911      }  // end if
1912
1913     }  // end if
1914
1915    }  // end for
1916
1917   }  // end if
1918
1919   if (   (  retVal = AllocSD ()  ) == NULL   ) __leave;
1920
1921   if (  !SetSecurityDescriptorDacl ( retVal, TRUE, pACL, TRUE )  ) __leave;
1922
1923   fOK = TRUE;
1924
1925  }  // end __try
1926
1927  __finally {
1928  
1929   if ( !fOK ) {
1930
1931    if ( retVal != NULL )
1932        
1933     FreeSD ( retVal );
1934
1935    else if ( pACL != NULL )
1936
1937     FreeAcl ( pACL );
1938
1939    retVal = NULL;
1940   
1941   }  // end if
1942
1943   if ( hProcess        != NULL ) CloseHandle          ( hProcess        );
1944   if ( pTkOwner        != NULL ) FreeTokenInformation ( pTkOwner        );
1945   if ( pTkGroups       != NULL ) FreeTokenInformation ( pTkGroups       );
1946   if ( pTkPrimaryGroup != NULL ) FreeTokenInformation ( pTkPrimaryGroup );
1947   if ( pfSD            != NULL ) FreeFileSecurity     ( pfSD            );
1948  
1949  }  // end __finally
1950
1951 #ifdef VAC
1952 leave: ;     // added for VisualAge
1953 #endif
1954
1955  return retVal;
1956  
1957 }  // end _osd_wnt_protection_to_sd */
1958
1959 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1960 #undef __try
1961 #undef __finally
1962 #undef __leave
1963 #endif
1964
1965 static void __fastcall _test_raise ( HANDLE hFile, Standard_CString str ) {
1966
1967  Standard_Character buff[ 64 ];
1968
1969  if (hFile == INVALID_HANDLE_VALUE) {
1970  
1971   _tcscpy (  buff, TEXT( "OSD_File :: " )  );
1972   _tcscat (  buff, str );
1973   _tcscat (  buff, TEXT( " (): wrong access" )  );
1974
1975   Standard_ProgramError :: Raise ( buff );
1976  
1977  }  // end if
1978
1979 }  // end _test_raise
1980
1981 // Modified so that we have <nl> at end of line if we have read <nl> or <cr>
1982 // by LD 17 dec 98 for B4.4
1983
1984 static DWORDLONG __fastcall _get_line ( Standard_PCharacter& buffer, DWORD dwBuffSize ) {
1985
1986  DWORDLONG        retVal;
1987  Standard_PCharacter ptr;
1988
1989  buffer[ dwBuffSize ] = 0;
1990  ptr                  = buffer;
1991
1992  while ( *ptr != 0 ) {
1993  
1994   if (  *ptr == TEXT( '\n' )  ) {
1995   
1996    ptr++ ;   // jump newline char.
1997    *ptr = 0 ;
1998    retVal = ptr - buffer - dwBuffSize;
1999    retVal &= 0x0000000FFFFFFFF;// import 32-bit to 64-bit
2000 #ifdef VAC
2001    retVal = (DWORDLONG) ( (unsigned __int64) retVal | (((unsigned __int64) ptr) << 32) );
2002 #else
2003    retVal |= (   (  ( DWORDLONG )( DWORD )ptr  ) << 32   );
2004 #endif   
2005    return retVal;
2006   
2007   } else if (  *ptr == TEXT( '\r' ) && ptr[ 1 ] == TEXT( '\n' )  ) {
2008   
2009    *(ptr++) = '\n' ; // Substitue carriage return by newline.
2010    *ptr = 0 ;
2011    retVal = ptr + 1 - buffer - dwBuffSize;
2012    retVal &= 0x0000000FFFFFFFF;// import 32-bit to 64-bit
2013 #ifdef VAC
2014    retVal = (DWORDLONG) ( (unsigned __int64) retVal | (((unsigned __int64) ptr) << 32) );
2015 #else
2016    retVal |= (   (  ( DWORDLONG )( DWORD )ptr  ) << 32   );
2017 #endif
2018    return retVal;
2019   
2020   } else if (  *ptr == TEXT( '\r' ) && ptr[ 1 ] == 0  ) {
2021     *ptr = '\n' ; // Substitue carriage return by newline
2022
2023 #ifdef VAC  
2024     return (DWORDLONG) (__int64) (-1);
2025 #else
2026     return 0xFFFFFFFFFFFFFFFF;
2027 #endif
2028   }
2029   ++ptr;
2030   
2031  }  // end while
2032
2033 #ifdef VAC
2034  retVal  = (DWORDLONG) ( ( (unsigned __int64) ((DWORD) buffer + dwBuffSize) ) << 32 );
2035  retVal = (DWORDLONG) ( (unsigned __int64) retVal & (((unsigned __int64) 0xFFFFFFFF) << 32) );
2036 #else
2037  retVal  = (   (  ( DWORDLONG )( ( DWORD )buffer + dwBuffSize )  ) << 32   );
2038  retVal &= 0xFFFFFFFF00000000;
2039 #endif
2040
2041  return retVal;
2042
2043 }  // end _get_line
2044
2045 static int __fastcall _get_buffer (
2046                         HANDLE hChannel,
2047                         Standard_PCharacter& buffer, 
2048                                    DWORD dwSize,
2049                         BOOL fPeek, BOOL fSocket
2050                        ) {
2051
2052  int   retVal = -1;
2053  int   flags;
2054  DWORD dwDummy;
2055  DWORD dwBytesRead;
2056
2057  if ( fSocket ) {
2058  
2059   flags = fPeek ? MSG_PEEK : 0;
2060
2061   retVal = recv (  ( SOCKET )hChannel, buffer, ( int )dwSize, flags  );
2062
2063   if ( retVal == SOCKET_ERROR ) retVal = -1;
2064
2065  } else {
2066  
2067   if ( fPeek ) {
2068    
2069    if (  !PeekNamedPipe (
2070            hChannel, buffer, dwSize, &dwBytesRead, &dwDummy, &dwDummy
2071           ) && GetLastError () != ERROR_BROKEN_PIPE
2072    )
2073
2074     retVal = -1;
2075
2076    else
2077
2078     retVal = ( int )dwBytesRead;
2079    
2080   } else {
2081
2082    if (  !ReadFile ( hChannel, buffer, dwSize, &dwBytesRead, NULL )  )
2083        
2084     retVal = -1;
2085
2086    else
2087
2088     retVal = ( int )dwBytesRead;
2089    
2090   }  // end else
2091  
2092  }  // end else
2093
2094  return retVal;
2095
2096 }  // end _get_buffer
2097
2098
2099 static DWORD __fastcall _get_access_mask ( OSD_SingleProtection prt ) {
2100
2101  DWORD retVal = 0;
2102
2103  switch ( prt ) {
2104  
2105   case OSD_None:
2106
2107    retVal = 0;
2108
2109   break;
2110
2111   case OSD_R:
2112
2113    retVal = FILE_GENERIC_READ;
2114
2115   break;
2116
2117   case OSD_W:
2118
2119    retVal = FILE_GENERIC_WRITE;
2120
2121   break;
2122
2123   case OSD_RW:
2124
2125    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
2126
2127   break;
2128
2129   case OSD_X:
2130
2131    retVal = FILE_GENERIC_EXECUTE;
2132
2133   break;
2134
2135   case OSD_RX:
2136
2137    retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
2138
2139   break;
2140
2141   case OSD_WX:
2142
2143    retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2144
2145   break;
2146
2147   case OSD_RWX:
2148
2149    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2150
2151   break;
2152
2153   case OSD_D:
2154
2155    retVal = DELETE;
2156
2157   break;
2158
2159   case OSD_RD:
2160
2161    retVal = FILE_GENERIC_READ | DELETE;
2162
2163   break;
2164
2165   case OSD_WD:
2166
2167    retVal = FILE_GENERIC_WRITE | DELETE;
2168
2169   break;
2170
2171   case OSD_RWD:
2172
2173    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
2174
2175   break;
2176
2177   case OSD_XD:
2178
2179    retVal = FILE_GENERIC_EXECUTE | DELETE;
2180
2181   break;
2182
2183   case OSD_RXD:
2184
2185    retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE;
2186
2187   break;
2188
2189   case OSD_WXD:
2190
2191    retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2192
2193   break;
2194
2195   case OSD_RWXD:
2196
2197    retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2198
2199   break;
2200
2201   default:
2202
2203    RAISE(  TEXT( "_get_access_mask (): incorrect parameter" )  );
2204  
2205  }  // end switch
2206
2207  return retVal;
2208
2209 }  // end _get_access_mask
2210
2211 static DWORD __fastcall _get_dir_access_mask ( OSD_SingleProtection prt ) {
2212
2213  DWORD retVal = 0;
2214
2215  switch ( prt ) {
2216  
2217   case OSD_None:
2218
2219    retVal = 0;
2220
2221   break;
2222
2223   case OSD_R:
2224
2225    retVal = GENERIC_READ;
2226
2227   break;
2228
2229   case OSD_W:
2230
2231    retVal = GENERIC_WRITE;
2232
2233   break;
2234
2235   case OSD_RW:
2236
2237    retVal = GENERIC_READ | GENERIC_WRITE;
2238
2239   break;
2240
2241   case OSD_X:
2242
2243    retVal = GENERIC_EXECUTE;
2244
2245   break;
2246
2247   case OSD_RX:
2248
2249    retVal = GENERIC_READ | GENERIC_EXECUTE;
2250
2251   break;
2252
2253   case OSD_WX:
2254
2255    retVal = GENERIC_WRITE | GENERIC_EXECUTE;
2256
2257   break;
2258
2259   case OSD_RWX:
2260
2261    retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE;
2262
2263   break;
2264
2265   case OSD_D:
2266
2267    retVal = DELETE;
2268
2269   break;
2270
2271   case OSD_RD:
2272
2273    retVal = GENERIC_READ | DELETE;
2274
2275   break;
2276
2277   case OSD_WD:
2278
2279    retVal = GENERIC_WRITE | DELETE;
2280
2281   break;
2282
2283   case OSD_RWD:
2284
2285    retVal = GENERIC_READ | GENERIC_WRITE | DELETE;
2286
2287   break;
2288
2289   case OSD_XD:
2290
2291    retVal = GENERIC_EXECUTE | DELETE;
2292
2293   break;
2294
2295   case OSD_RXD:
2296
2297    retVal = GENERIC_READ | GENERIC_EXECUTE | DELETE;
2298
2299   break;
2300
2301   case OSD_WXD:
2302
2303    retVal = GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2304
2305   break;
2306
2307   case OSD_RWXD:
2308
2309    retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2310
2311   break;
2312
2313   default:
2314
2315    RAISE(  TEXT( "_get_dir_access_mask (): incorrect parameter" )  );
2316  
2317  }  // end switch
2318
2319  return retVal;
2320
2321 }  // end _get_dir_access_mask
2322
2323 static HANDLE __fastcall _open_file (
2324                           Standard_CString fName,
2325                           OSD_OpenMode oMode,
2326                           DWORD dwOptions, LPBOOL fNew
2327                          ) {
2328
2329  HANDLE retVal = INVALID_HANDLE_VALUE;
2330  DWORD  dwDesiredAccess = 0;
2331  DWORD  dwCreationDistribution;
2332
2333  switch ( oMode ) {
2334   
2335   case OSD_ReadOnly:
2336
2337    dwDesiredAccess = GENERIC_READ;
2338
2339   break;
2340
2341   case OSD_WriteOnly:
2342
2343    dwDesiredAccess = GENERIC_WRITE;
2344
2345   break;
2346
2347   case OSD_ReadWrite:
2348
2349    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
2350
2351   break;
2352
2353   default:
2354
2355    RAISE(  TEXT( "_open_file (): incorrect parameter" )  );
2356   
2357  }  // end switch
2358
2359  dwCreationDistribution = ( dwOptions != OPEN_NEW ) ? OPEN_EXISTING : CREATE_ALWAYS;
2360
2361  retVal = CreateFile (
2362            fName, dwDesiredAccess,
2363            FILE_SHARE_READ | FILE_SHARE_WRITE,
2364            NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2365           );
2366
2367  if ( retVal          == INVALID_HANDLE_VALUE &&
2368       dwOptions       == OPEN_APPEND          &&
2369       GetLastError () == ERROR_FILE_NOT_FOUND
2370  ) {
2371
2372  
2373   dwCreationDistribution = CREATE_ALWAYS;
2374   
2375   retVal = CreateFile (
2376             fName, dwDesiredAccess,
2377             FILE_SHARE_READ | FILE_SHARE_WRITE,
2378             NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2379            );
2380
2381   *fNew = TRUE;
2382
2383  }  // end if
2384
2385  return retVal;
2386
2387 }  // end _open_file
2388
2389 Standard_Integer __fastcall _get_file_type (
2390                              Standard_CString fName, HANDLE fileHandle
2391                             ) {
2392
2393  Standard_Integer retVal = 0;
2394  DWORD            dwType;
2395  int              fileType;
2396
2397  fileType = (fileHandle == INVALID_HANDLE_VALUE ? 
2398              FILE_TYPE_DISK : GetFileType (fileHandle));
2399
2400  switch ( fileType ) {
2401  
2402   case FILE_TYPE_UNKNOWN:
2403
2404    retVal = FLAG_SOCKET;
2405
2406   break;
2407
2408   case FILE_TYPE_DISK:
2409
2410    if (   (  dwType = GetFileAttributes ( fName )  ) != 0xFFFFFFFF  )
2411
2412     retVal =  dwType & FILE_ATTRIBUTE_DIRECTORY ? FLAG_DIRECTORY : FLAG_FILE;
2413
2414    else
2415
2416     retVal = 0x80000000;
2417
2418   break;
2419
2420   case FILE_TYPE_CHAR:
2421
2422    retVal = FLAG_DEVICE;
2423
2424   break;
2425
2426   case FILE_TYPE_PIPE:
2427
2428    retVal = FLAG_PIPE;
2429
2430   break;
2431  
2432  }  // end switch
2433
2434  return retVal;
2435
2436 }  // end _get_file_type
2437
2438 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2439 #define __try
2440 #define __finally
2441 #define __leave return retVal
2442 #endif
2443
2444 BOOL __fastcall _osd_wnt_sd_to_protection (
2445                  PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL fDir
2446                 ) {
2447
2448  int           i;
2449  BOOL          fPresent;
2450  BOOL          fDefaulted;
2451  PACL          pACL;
2452  PSID          pSIDowner;
2453  PSID          pSIDadmin;
2454  PSID          pSIDworld;
2455  LPVOID        pACE;
2456  DWORD         dwAccessOwner = 0;
2457  DWORD         dwAccessGroup = 0;
2458  DWORD         dwAccessAdmin = 0;
2459  DWORD         dwAccessWorld = 0;
2460  BOOL          retVal = FALSE;
2461  GET_PROT_FUNC _get_prot_func = fDir ? &_get_protection_dir : &_get_protection;
2462
2463  __try {
2464
2465   if (  !GetSecurityDescriptorOwner ( pSD, &pSIDowner, &fDefaulted )  ) __leave;
2466
2467   if (  !GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDefaulted ) ||
2468         !fPresent
2469   ) __leave;
2470
2471   if ( pSIDowner == NULL || pACL == NULL ) {
2472   
2473    SetLastError ( ERROR_NO_SECURITY_ON_OBJECT );
2474    __leave;
2475   
2476   }  // end if
2477  
2478   pSIDadmin = AdminSid ();
2479   pSIDworld = WorldSid ();
2480
2481   for ( i = 0; i < ( int )pACL -> AceCount; ++i ) {
2482   
2483    if (  GetAce ( pACL, i, &pACE )  ) {
2484    
2485     if (   EqualSid (  pSIDowner, GET_SID( pACE )  )   )
2486
2487      dwAccessOwner = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2488                      0 : *GET_MSK( pACE );
2489
2490     else if (   EqualSid (  pSIDadmin, GET_SID( pACE )  )   )
2491
2492      dwAccessAdmin = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2493                      0 : *GET_MSK( pACE );
2494
2495     else if (   EqualSid (  pSIDworld, GET_SID( pACE )  )   )
2496
2497      dwAccessWorld = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2498                      0 : *GET_MSK( pACE );
2499
2500     else
2501
2502      dwAccessGroup = (  ( PACE_HEADER )pACE  ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2503                      0 : *GET_MSK( pACE );
2504    
2505    }  // end if
2506   
2507   }  // end for
2508
2509   prot.SetValues (
2510         ( *_get_prot_func ) ( dwAccessAdmin ),
2511         ( *_get_prot_func ) ( dwAccessOwner ),
2512         ( *_get_prot_func ) ( dwAccessGroup ),
2513         ( *_get_prot_func ) ( dwAccessWorld )
2514        );
2515
2516   retVal = TRUE;
2517   
2518  }  // end __try
2519
2520  __finally {}
2521        
2522 #ifdef VAC
2523 leave: ;      // added for VisualAge
2524 #endif
2525
2526  return retVal;
2527
2528 }  // end _osd_wnt_sd_to_protection
2529
2530 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2531 #undef __try
2532 #undef __finally
2533 #undef __leave
2534 #endif
2535
2536 static OSD_SingleProtection __fastcall _get_protection ( DWORD mask ) {
2537
2538  OSD_SingleProtection retVal;
2539
2540  switch ( mask ) {
2541  
2542   case FILE_GENERIC_READ:
2543
2544    retVal = OSD_R;
2545
2546   break;
2547
2548   case FILE_GENERIC_WRITE:
2549
2550    retVal = OSD_W;
2551
2552   break;
2553
2554   case FILE_GENERIC_READ | FILE_GENERIC_WRITE:
2555
2556    retVal = OSD_RW;
2557
2558   break;
2559
2560   case FILE_GENERIC_EXECUTE:
2561
2562    retVal = OSD_X;
2563
2564   break;
2565
2566   case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE:
2567
2568    retVal = OSD_RX;
2569
2570   break;
2571
2572   case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2573
2574    retVal = OSD_WX;
2575
2576   break;
2577
2578   case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2579
2580    retVal = OSD_RWX;
2581
2582   break;
2583
2584   case DELETE:
2585
2586    retVal = OSD_D;
2587
2588   break;
2589
2590   case FILE_GENERIC_READ | DELETE:
2591
2592    retVal = OSD_RD;
2593
2594   break;
2595
2596   case FILE_GENERIC_WRITE | DELETE:
2597
2598    retVal = OSD_WD;
2599
2600   break;
2601
2602   case FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE:
2603
2604    retVal = OSD_RWD;
2605
2606   break;
2607
2608   case FILE_GENERIC_EXECUTE | DELETE:
2609
2610    retVal = OSD_XD;
2611
2612   break;
2613
2614   case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE:
2615
2616    retVal = OSD_RXD;
2617
2618   break;
2619
2620   case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2621
2622    retVal = OSD_WXD;
2623
2624   break;
2625
2626   case FILE_ALL_ACCESS:
2627   case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2628
2629    retVal = OSD_RWXD;
2630
2631   break;
2632
2633   case 0:
2634   default:
2635
2636    retVal = OSD_None;
2637  
2638  }  // end switch
2639
2640  return retVal;
2641
2642 }  // end _get_protection
2643
2644 static OSD_SingleProtection __fastcall _get_protection_dir ( DWORD mask ) {
2645
2646  OSD_SingleProtection retVal;
2647
2648  switch ( mask ) {
2649  
2650   case GENERIC_READ:
2651
2652    retVal = OSD_R;
2653
2654   break;
2655
2656   case GENERIC_WRITE:
2657
2658    retVal = OSD_W;
2659
2660   break;
2661
2662   case GENERIC_READ | GENERIC_WRITE:
2663
2664    retVal = OSD_RW;
2665
2666   break;
2667
2668   case GENERIC_EXECUTE:
2669
2670    retVal = OSD_X;
2671
2672   break;
2673
2674   case GENERIC_READ | GENERIC_EXECUTE:
2675
2676    retVal = OSD_RX;
2677
2678   break;
2679
2680   case GENERIC_WRITE | GENERIC_EXECUTE:
2681
2682    retVal = OSD_WX;
2683
2684   break;
2685
2686   case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE:
2687
2688    retVal = OSD_RWX;
2689
2690   break;
2691
2692   case DELETE:
2693
2694    retVal = OSD_D;
2695
2696   break;
2697
2698   case GENERIC_READ | DELETE:
2699
2700    retVal = OSD_RD;
2701
2702   break;
2703
2704   case GENERIC_WRITE | DELETE:
2705
2706    retVal = OSD_WD;
2707
2708   break;
2709
2710   case GENERIC_READ | GENERIC_WRITE | DELETE:
2711
2712    retVal = OSD_RWD;
2713
2714   break;
2715
2716   case GENERIC_EXECUTE | DELETE:
2717
2718    retVal = OSD_XD;
2719
2720   break;
2721
2722   case GENERIC_READ | GENERIC_EXECUTE | DELETE:
2723
2724    retVal = OSD_RXD;
2725
2726   break;
2727
2728   case GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2729
2730    retVal = OSD_WXD;
2731
2732   break;
2733
2734   case FILE_ALL_ACCESS:
2735   case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2736
2737    retVal = OSD_RWXD;
2738
2739   break;
2740
2741   case 0:
2742   default:
2743
2744    retVal = OSD_None;
2745  
2746  }  // end switch
2747
2748  return retVal;
2749
2750 }  // end _get_protection_dir
2751
2752 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2753 #define __try
2754 #define __finally
2755 #define __leave return fOK
2756 #endif
2757
2758 BOOL __fastcall _osd_print (const Standard_PCharacter pName, Standard_CString fName ) {
2759
2760  BOOL   fOK, fJob;                
2761  HANDLE hPrinter = NULL;
2762  BYTE   jobInfo[ MAX_PATH + sizeof ( DWORD ) ];
2763  DWORD  dwNeeded, dwCode = 0;
2764
2765  fOK = fJob = FALSE;
2766
2767  __try {
2768  
2769   if (  !OpenPrinter ( Standard_PCharacter(pName), &hPrinter, NULL )  ) {
2770   
2771    hPrinter = NULL;
2772    __leave;
2773   
2774   }  // end if
2775
2776   if (   !AddJob (
2777            hPrinter, 1, jobInfo, MAX_PATH + sizeof ( DWORD ), &dwNeeded
2778           )
2779   ) __leave;
2780
2781   fJob = TRUE;
2782
2783   if (  !CopyFile (
2784           fName, (  ( ADDJOB_INFO_1* )jobInfo  ) -> Path, FALSE
2785          )
2786   ) __leave;
2787
2788   if (  !ScheduleJob (
2789           hPrinter, (  ( ADDJOB_INFO_1* )jobInfo  ) -> JobId
2790          )
2791   ) __leave;
2792   
2793   fOK = TRUE;
2794  
2795  }  // end __try
2796
2797  __finally {
2798  
2799   if ( !fOK ) {
2800   
2801    BYTE  info[ 1024 ];
2802    DWORD dwBytesNeeded;
2803
2804    dwCode = GetLastError ();
2805
2806    if ( fJob && hPrinter != NULL ) {
2807
2808     GetJob (
2809      hPrinter, (  ( ADDJOB_INFO_1* )jobInfo  ) -> JobId, 1, 
2810      info, 1024, &dwBytesNeeded
2811     );
2812
2813     if ( fJob ) SetJob (
2814                  hPrinter,
2815                  (  ( ADDJOB_INFO_1* )jobInfo  ) -> JobId,
2816                  1, info, JOB_CONTROL_CANCEL
2817                 );
2818
2819    }  // end if
2820
2821   }  // end if
2822
2823   if ( hPrinter != NULL ) ClosePrinter ( hPrinter );
2824  
2825  }  // end __finally
2826
2827 #ifdef VAC
2828 leave: ;       // added for VisualAge
2829 #endif
2830
2831  if ( !fOK ) SetLastError ( dwCode );
2832
2833  return fOK;
2834                 
2835 }  // end _osd_print
2836
2837 #if defined(__CYGWIN32__) || defined(__MINGW32__)
2838 #undef __try
2839 #undef __finally
2840 #undef __leave
2841 #endif
2842
2843 Standard_Boolean OSD_File::IsReadable()
2844 {
2845   TCollection_AsciiString FileName ;
2846   HANDLE Channel ;
2847
2848   myPath.SystemName(FileName) ;
2849   Channel = _open_file(FileName.ToCString(), OSD_ReadOnly, OPEN_OLD) ;
2850   if (Channel == INVALID_HANDLE_VALUE)
2851     return Standard_False ;
2852   else {
2853     CloseHandle (Channel) ;
2854     return Standard_True ;
2855   }
2856 }
2857
2858
2859 Standard_Boolean OSD_File::IsWriteable()
2860 {
2861   TCollection_AsciiString FileName ;
2862   HANDLE Channel ;
2863
2864   myPath.SystemName(FileName) ;
2865   Channel = _open_file(FileName.ToCString(), OSD_ReadWrite, OPEN_OLD) ;
2866   if (Channel == INVALID_HANDLE_VALUE)
2867     return Standard_False ;
2868   else {
2869     CloseHandle (Channel) ;
2870     return Standard_True ;
2871   }
2872 }
2873
2874 Standard_Boolean OSD_File::IsExecutable()
2875 {
2876   return IsReadable() ;
2877
2878 //  if (_access(FileName.ToCString(),0))
2879 }
2880
2881 #endif /* _WIN32 */
2882
2883
2884 // ---------------------------------------------------------------------
2885 // Read lines in a file while it is increasing.
2886 // Each line is terminated with a <nl>.
2887 // ---------------------------------------------------------------------
2888
2889 #include <OSD.hxx>
2890
2891 Standard_Boolean OSD_File::ReadLastLine(TCollection_AsciiString& aLine,const Standard_Integer aDelay,const Standard_Integer aNbTries)
2892 {
2893   static Standard_Integer MaxLength = 1000 ;
2894   Standard_Integer Len ;
2895   Standard_Integer Count = aNbTries ;
2896
2897   if (Count <= 0)
2898       return Standard_False ;
2899   for(;;) {
2900     ReadLine(aLine, MaxLength, Len) ;
2901     if (!aLine.IsEmpty()) 
2902       return Standard_True ;
2903     if (!--Count)
2904       return Standard_False ;
2905     OSD::SecSleep(aDelay) ;
2906   }
2907 }
2908
2909
2910 Standard_Boolean OSD_File::Edit()
2911 {
2912   cout << "Function OSD_File::Edit() not yet implemented." << endl;
2913   return Standard_False ;
2914 }
2915
2916
2917
2918