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