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