0028110: Configuration - specify Unicode charset instead of multibyte in project...
[occt.git] / src / OSD / OSD_File.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15//------------------------------------------------------------------------
16// UNIX Part
17//------------------------------------------------------------------------
18
6ff736d8 19#ifndef _WIN32
7fd59977 20
42cf5bc1 21
22#include <OSD_File.hxx>
23#include <OSD_FromWhere.hxx>
7fd59977 24#include <OSD_OSDError.hxx>
42cf5bc1 25#include <OSD_Path.hxx>
42cf5bc1 26#include <OSD_Protection.hxx>
7fd59977 27#include <OSD_WhoAmI.hxx>
7fd59977 28#include <Standard_PCharacter.hxx>
42cf5bc1 29#include <Standard_ProgramError.hxx>
30#include <TCollection_AsciiString.hxx>
7fd59977 31
32const OSD_WhoAmI Iam = OSD_WFile;
33
34#if defined (sun) || defined(SOLARIS)
35#define POSIX
36#else
37#define SYSV
38#endif
39
40#include <errno.h>
7fd59977 41#include <stdlib.h>
42#include <stdio.h>
43#include <fcntl.h>
03155c18 44#include <unistd.h>
45#include <sys/stat.h>
7fd59977 46
47#define NEWLINE '\10';
48
49// ---------------------------------------------------------------------
50// Create an empty file object
51// ---------------------------------------------------------------------
52
6ff736d8 53OSD_File::OSD_File():OSD_FileNode()
54{
7fd59977 55 ImperativeFlag = Standard_False;
56 myLock = OSD_NoLock;
57 myIO = 0;
58 myMode = OSD_ReadWrite;
7fd59977 59 myFILE = (Standard_Address) NULL;
6ff736d8 60 myFileChannel = -1;
61 myFileHandle = 0;
7fd59977 62}
63
64// ---------------------------------------------------------------------
65// Create and initialize a file object
66// ---------------------------------------------------------------------
67
6ff736d8 68OSD_File::OSD_File(const OSD_Path& Name):OSD_FileNode(Name)
69{
7fd59977 70 ImperativeFlag = Standard_False;
71 myLock = OSD_NoLock;
72 myIO = 0;
73 myMode = OSD_ReadWrite;
7fd59977 74 myFILE = (Standard_Address) NULL;
6ff736d8 75 myFileChannel = -1;
76 myFileHandle = 0;
7fd59977 77}
78
6ff736d8 79// protect against occasional use of myFileHande in Linux code
80#define myFileHandle myFileHandle_is_only_for_Windows
7fd59977 81
82// ---------------------------------------------------------------------
83// Build a file if it doesn't exist or create again if it already exists
84// ---------------------------------------------------------------------
85
86void OSD_File::Build(const OSD_OpenMode Mode,
87 const OSD_Protection& Protect){
88
89 Standard_Integer internal_prot;
90 Standard_Integer internal_mode = O_CREAT | O_TRUNC ;
91 TCollection_AsciiString aBuffer;
92
93 if (myPath.Name().Length()==0)
94 Standard_ProgramError::Raise("OSD_File::Build : no name was given");
95
96 if (myFileChannel != -1)
97 Standard_ProgramError::Raise("OSD_File::Build : file is already open");
98
99
100 myMode = Mode;
101
102 internal_prot = Protect.Internal();
103
6ff736d8 104 const char* CMode = "r";
7fd59977 105
106 switch (Mode){
107 case OSD_ReadOnly:
108 internal_mode |= O_RDONLY;
6ff736d8 109 CMode = "r";
7fd59977 110 break;
111 case OSD_WriteOnly:
112 internal_mode |= O_WRONLY;
6ff736d8 113 CMode = "w";
7fd59977 114 break;
115 case OSD_ReadWrite:
116 internal_mode |= O_RDWR;
6ff736d8 117 CMode = "w+";
7fd59977 118 break;
119 }
120
121 myPath.SystemName( aBuffer );
6ff736d8 122 myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
7fd59977 123 if (myFileChannel >= 0) {
6ff736d8 124 myFILE = fdopen (myFileChannel, CMode);
7fd59977 125 }
126 else
127 /* Handle OPEN errors */
128
129 myError.SetValue (errno, Iam, "Open");
130
131}
132
133
134
135// ---------------------------------------------------------------------
136// Append to an existing file
137// ---------------------------------------------------------------------
138
139void OSD_File::Append(const OSD_OpenMode Mode,
140 const OSD_Protection& Protect){
141
142 Standard_Integer internal_prot;
143 Standard_Integer internal_mode = O_APPEND;;
144 TCollection_AsciiString aBuffer;
145
146 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
147 Standard_ProgramError::Raise("OSD_File::Append : it is a directory");
148 }
149
150 if (myPath.Name().Length()==0)
151 Standard_ProgramError::Raise("OSD_File::Append : no name was given");
152
153 if (myFileChannel != -1)
154 Standard_ProgramError::Raise("OSD_File::Append : file is already open");
155
156 internal_prot = Protect.Internal();
7fd59977 157 myMode = Mode;
6ff736d8 158 const char* CMode = "r";
7fd59977 159
160 switch (Mode){
161 case OSD_ReadOnly:
162 internal_mode |= O_RDONLY;
6ff736d8 163 CMode = "r";
7fd59977 164 break;
165 case OSD_WriteOnly:
166 internal_mode |= O_WRONLY;
6ff736d8 167 CMode = "a";
7fd59977 168 break;
169 case OSD_ReadWrite:
170 internal_mode |= O_RDWR;
6ff736d8 171 CMode = "a+";
7fd59977 172 break;
173 }
174
175 // If file doesn't exist, creates it.
176
177 if (!Exists()) internal_mode |= O_CREAT;
178
179 myPath.SystemName ( aBuffer );
6ff736d8 180 myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
7fd59977 181 if (myFileChannel >= 0)
6ff736d8 182 myFILE = fdopen (myFileChannel, CMode);
7fd59977 183 else
184 /* Handle OPEN errors */
185
186 myError.SetValue (errno, Iam, "Open");
187}
188
189// ---------------------------------------------------------------------
190// Open a file
191// ---------------------------------------------------------------------
192
193void OSD_File::Open(const OSD_OpenMode Mode,
194 const OSD_Protection& Protect){
195
196 Standard_Integer internal_prot;
197 Standard_Integer internal_mode = 0;
198 TCollection_AsciiString aBuffer;
199
200 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
201 myError.SetValue (1, Iam, "Could not be open : it is a directory");
202 }
203
204 if (myPath.Name().Length()==0)
205 Standard_ProgramError::Raise("OSD_File::Open : no name was given");
206
207 if (myFileChannel != -1)
208 Standard_ProgramError::Raise("OSD_File::Open : file is already open");
209
210 internal_prot = Protect.Internal();
7fd59977 211 myMode = Mode;
6ff736d8 212 const char* CMode = "r";
7fd59977 213
214 switch (Mode){
215 case OSD_ReadOnly:
216 internal_mode |= O_RDONLY;
6ff736d8 217 CMode = "r";
7fd59977 218 break;
219 case OSD_WriteOnly:
220 internal_mode |= O_WRONLY;
6ff736d8 221 CMode = "w";
7fd59977 222 break;
223 case OSD_ReadWrite:
224 internal_mode |= O_RDWR;
6ff736d8 225 CMode = "w+";
7fd59977 226 break;
227 }
228
229 myPath.SystemName ( aBuffer );
6ff736d8 230 myFileChannel = open (aBuffer.ToCString(), internal_mode, internal_prot);
7fd59977 231 if (myFileChannel >= 0)
6ff736d8 232 myFILE = fdopen (myFileChannel, CMode);
7fd59977 233 else
234 /* Handle OPEN errors */
235
236 myError.SetValue (errno, Iam, "Open");
237}
238
239
240
241// ---------------------------------------------------------------------
242// ---------------------------------------------------------------------
95e05159 243void OSD_File::BuildTemporary(){
244
245 if ( IsOpen() )
246 Close();
7fd59977 247
248#if defined(vax) || defined(__vms) || defined(VAXVMS)
249 FILE *fic;
7fd59977 250 int dummy;
251
252 fic = tmpfile();
6ff736d8 253 dummy = open("dummy", O_RDWR | O_CREAT); // Open a dummy file
95e05159 254 myFileChannel = dummy - 1; // This is file channel of "fic" +1
7fd59977 255 close(dummy); // Close dummy file
256 unlink("dummy"); // Removes dummy file
257
258#else
95e05159 259 char name[] = "/tmp/CSFXXXXXX";
260 myFileChannel = mkstemp( name );
7fd59977 261
262 TCollection_AsciiString aName ( name ) ;
263 OSD_Path aPath( aName ) ;
264
95e05159 265 SetPath( aPath ) ;
7fd59977 266
95e05159 267 myFILE = fdopen( myFileChannel, "w+" ) ;
7fd59977 268
269#endif
270
95e05159 271 myMode = OSD_ReadWrite;
7fd59977 272}
273
274
275
276// ---------------------------------------------------------------------
277// Read content of a file
278// ---------------------------------------------------------------------
279
280void 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
6ff736d8 303 status = read (myFileChannel, readbuf, Nbyte);
7fd59977 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
317void 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 {
6ff736d8 356 NByteRead = (Standard_Integer)strlen(abuffer);
7fd59977 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// --------------------------------------------------------------------------
364OSD_KindFile OSD_File::KindOfFile ( ) const{
365int status;
366struct stat buffer;
367TCollection_AsciiString FullName;
368OSD_Path aPath;
369
370Path(aPath);
371aPath.SystemName (FullName);
372status = stat (FullName.ToCString() , &buffer );
373if ( 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}
380return OSD_UNKNOWN ;
381
382}
383// --------------------------------------------------------------------------
384// Read content of a file
385// --------------------------------------------------------------------------
7c65581d 386void OSD_File::Read(const Standard_Address Buffer,
7fd59977 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
6ff736d8 411 status = read (myFileChannel, (char*) Buffer, Nbyte);
7fd59977 412
413 if (status == -1) myError.SetValue (errno, Iam, "Read");
414 else{
415 if ( status < Nbyte ) myIO = EOF;
6ff736d8 416 Readbyte = status;
7fd59977 417 }
418}
419
420// Write content of a file
421
422void 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
6ff736d8 445 status = write (myFileChannel, writebuf, Nbyte);
7fd59977 446
447 if ( status == -1) myError.SetValue (errno, Iam, "Write");
448 else
449 if ( status < Nbyte ) myIO = EOF;
450}
451
452
453void 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
6ff736d8 470 status = write (myFileChannel, (const char *)Buffer, Nbyte);
7fd59977 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
483void OSD_File::Seek(const Standard_Integer Offset,
484 const OSD_FromWhere Whence){
6ff736d8 485 int iwhere=0;
7fd59977 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 :
6ff736d8 494 iwhere = SEEK_SET;
7fd59977 495 break;
496 case OSD_FromHere:
6ff736d8 497 iwhere = SEEK_CUR;
7fd59977 498 break;
499 case OSD_FromEnd:
6ff736d8 500 iwhere = SEEK_END;
7fd59977 501 break;
502 default :
503 myError.SetValue (EINVAL, Iam, "Seek");
504 }
7fd59977 505
6ff736d8 506 off_t status = lseek (myFileChannel, Offset, iwhere);
7fd59977 507 if (status == -1) myError.SetValue (errno, Iam, "Seek");
508}
509
510
511
512
513
514
515// Close a file
516
517void 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
6ff736d8 525 // note: it probably should be single call to fclose()...
526 status = close (myFileChannel);
7fd59977 527
528 if (status == -1) myError.SetValue (errno, Iam, "Close");
529 myFileChannel = -1;
530 if ( myFILE != NULL ) {
531 status = fclose ( (FILE*) myFILE );
6ff736d8 532 myFILE = NULL;
7fd59977 533 }
534 myIO = 0;
535}
536
537
538
539
540// --------------------------------------------------------------------------
541// Test if at end of file
542// --------------------------------------------------------------------------
543
544Standard_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
566void OSD_File::SetLock(const OSD_LockType Lock){
567int 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
6ff736d8 587 if (fstat (myFileChannel, &buf) == -1) {
7fd59977 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
6ff736d8 615 status = fcntl (myFileChannel, F_SETLKW, &key);
7fd59977 616 if (status == -1) myError.SetValue (errno, Iam, "SetLock");
617 else myLock = Lock;
618
619 if (Lock == OSD_ExclusiveLock){
6ff736d8 620 fstat (myFileChannel, &buf);
7fd59977 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
6ff736d8 639 status = flock (myFileChannel, lock);
7fd59977 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
651void OSD_File::UnLock(){
652int 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){
6ff736d8 674 fstat (myFileChannel, &buf);
7fd59977 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;
6ff736d8 681 status = fcntl (myFileChannel, F_SETLK, &key);
7fd59977 682 if (status == -1) myError.SetValue (errno, Iam, "UnSetLock");
683#else
684
6ff736d8 685 status = flock (myFileChannel, LOCK_UN);
7fd59977 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
698OSD_LockType OSD_File::GetLock(){
7fd59977 699 return(myLock);
700}
701
702
703
704
705// --------------------------------------------------------------------------
706// Return size of a file
707// --------------------------------------------------------------------------
708
6ff736d8 709Standard_Size OSD_File::Size(){
7fd59977 710 struct stat buffer;
711 int status;
712
713 if (myPath.Name().Length()==0)
714 Standard_ProgramError::Raise("OSD_File::Size : empty file name");
715
716 TCollection_AsciiString aBuffer;
717 myPath.SystemName ( aBuffer );
718 status = stat( aBuffer.ToCString() ,&buffer );
719 if (status == -1) {
720 myError.SetValue (errno, Iam, "Size");
6ff736d8 721 return 0;
7fd59977 722 }
723
6ff736d8 724 return (Standard_Size)buffer.st_size;
7fd59977 725}
726
7fd59977 727// --------------------------------------------------------------------------
728// Test if a file is open
729// --------------------------------------------------------------------------
730
731Standard_Boolean OSD_File::IsOpen()const{
7fd59977 732 return (myFileChannel != -1);
733}
734
735
736Standard_Boolean OSD_File::IsLocked(){
7fd59977 737 return(myLock != OSD_NoLock);
738}
739
740Standard_Boolean OSD_File::IsReadable()
741{
742 TCollection_AsciiString FileName ;
743
744 myPath.SystemName(FileName) ;
745
746 if (access(FileName.ToCString(),F_OK|R_OK))
747 return Standard_False;
748 else
749 return Standard_True;
750}
751
752Standard_Boolean OSD_File::IsWriteable()
753{
754 TCollection_AsciiString FileName ;
755
756 myPath.SystemName(FileName) ;
757
758 if (access(FileName.ToCString(),F_OK|R_OK|W_OK))
759 return Standard_False;
760 else
761 return Standard_True;
762}
763
764Standard_Boolean OSD_File::IsExecutable()
765{
766 TCollection_AsciiString FileName ;
767
768 myPath.SystemName(FileName) ;
769
770 if (access(FileName.ToCString(),F_OK|X_OK))
771 return Standard_False;
772 else
773 return Standard_True;
774}
775
95e05159 776int OSD_File::Capture(int theDescr) {
777 // Duplicate an old file descriptor of the given one to be able to restore output to it later.
778 int oldDescr = dup(theDescr);
779 // Redirect the output to this file
780 dup2(myFileChannel, theDescr);
781
782 // Return the old descriptor
783 return oldDescr;
784}
785
786void OSD_File::Rewind() {
787 rewind((FILE*)myFILE);
788}
789
6ff736d8 790#else /* _WIN32 */
7fd59977 791
792//------------------------------------------------------------------------
793//------------------- Windows NT sources for OSD_File -------------------
794//------------------------------------------------------------------------
795
796#include <windows.h>
797
798#include <OSD_File.hxx>
799#include <OSD_Protection.hxx>
7fd59977 800#include <Standard_ProgramError.hxx>
801
802#include <OSD_WNT_1.hxx>
803
804#include <stdio.h>
805#include <io.h>
806#include <Standard_PCharacter.hxx>
d9ff84e8 807#include <TCollection_ExtendedString.hxx>
7fd59977 808
742cc8b0 809#include <Strsafe.h>
810
7fd59977 811#if defined(__CYGWIN32__) || defined(__MINGW32__)
812#define VAC
7fd59977 813#endif
814
7fd59977 815#define ACE_HEADER_SIZE ( sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) )
816
817#define RAISE( arg ) Standard_ProgramError :: Raise ( ( arg ) )
6ff736d8 818#define TEST_RAISE( arg ) _test_raise ( myFileHandle, ( arg ) )
7fd59977 819
820#define OPEN_NEW 0
821#define OPEN_OLD 1
822#define OPEN_APPEND 2
823
824void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
742cc8b0 825#ifndef OCCT_UWP
fb0b0531 826PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, const wchar_t* );
7fd59977 827BOOL __fastcall _osd_wnt_sd_to_protection (
828 PSECURITY_DESCRIPTOR, OSD_Protection&, BOOL
829 );
742cc8b0 830static int __fastcall _get_buffer(HANDLE, Standard_PCharacter&, DWORD, BOOL, BOOL);
831#endif
6ff736d8 832static void __fastcall _test_raise ( HANDLE, Standard_CString );
68299304 833static Standard_Integer __fastcall _get_line (Standard_PCharacter& buffer, DWORD dwBuffSize, LONG& theSeekPos);
7fd59977 834static DWORD __fastcall _get_access_mask ( OSD_SingleProtection );
835static DWORD __fastcall _get_dir_access_mask ( OSD_SingleProtection prt );
836static HANDLE __fastcall _open_file ( Standard_CString, OSD_OpenMode, DWORD, LPBOOL = NULL );
837
838static OSD_SingleProtection __fastcall _get_protection ( DWORD );
839static OSD_SingleProtection __fastcall _get_protection_dir ( DWORD );
840
841typedef OSD_SingleProtection ( __fastcall *GET_PROT_FUNC ) ( DWORD );
842
6ff736d8 843Standard_Integer __fastcall _get_file_type ( Standard_CString, HANDLE );
7fd59977 844
845// ---------------------------------------------------------------------
846// Create an empty file object
847// ---------------------------------------------------------------------
848
6ff736d8 849OSD_File :: OSD_File ()
850{
7fd59977 851 ImperativeFlag = Standard_False;
852 myLock = OSD_NoLock;
853 myIO = 0;
6ff736d8 854 myFileChannel = -1;
855 myFileHandle = INVALID_HANDLE_VALUE;
7fd59977 856} // end constructor ( 1 )
857
858// ---------------------------------------------------------------------
859// Create and initialize a file object
860// ---------------------------------------------------------------------
861
6ff736d8 862OSD_File :: OSD_File ( const OSD_Path& Name ) : OSD_FileNode ( Name )
863{
7fd59977 864 ImperativeFlag = Standard_False;
865 myLock = OSD_NoLock;
866 myIO = 0;
867 myPath = Name;
6ff736d8 868 myFileChannel = -1;
869 myFileHandle = INVALID_HANDLE_VALUE;
7fd59977 870} // end constructor ( 2 )
871
95e05159 872// ---------------------------------------------------------------------
873// Redirect a standard handle (fileno(stdout), fileno(stdin) or
874// fileno(stderr) to this OSD_File and return the copy of the original
875// standard handle.
876// Example:
877// OSD_File aTmp;
878// aTmp.BuildTemporary();
879// int stdfd = _fileno(stdout);
880//
881// int oldout = aTmp.Capture(stdfd);
882// cout << "Some output to the file" << endl;
883// cout << flush;
884// fflush(stdout);
885//
886// _dup2(oldout, stdfd); // Restore standard output
887// aTmp.Close();
888// ---------------------------------------------------------------------
889int OSD_File::Capture(int theDescr) {
890 // Get POSIX file descriptor from this file handle
891 int dFile = _open_osfhandle(reinterpret_cast<intptr_t>(myFileHandle), myMode);
892
893 if (0 > dFile)
894 {
895 _osd_wnt_set_error ( myError, OSD_WFile, myFileHandle );
896 return -1;
897 }
898
899 // Duplicate an old file descriptor of the given one to be able to restore output to it later.
900 int oldDescr = _dup(theDescr);
901 // Redirect the output to this file
902 _dup2(dFile, theDescr);
903
904 // Return the old descriptor
905 return oldDescr;
906}
907
908void OSD_File::Rewind() {
c8c250a5 909 LARGE_INTEGER aDistanceToMove;
742cc8b0 910 aDistanceToMove.QuadPart = 0;
911 SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_BEGIN);
95e05159 912}
913
6ff736d8 914// protect against occasional use of myFileHande in Windows code
915#define myFileChannel myFileChannel_is_only_for_Linux
916
7fd59977 917// ---------------------------------------------------------------------
918// Build a file if it doesn't exist or create again if it already exists
919// ---------------------------------------------------------------------
920
742cc8b0 921void OSD_File :: Build ( const OSD_OpenMode Mode, const OSD_Protection& Protect) {
7fd59977 922
923 TCollection_AsciiString fName;
924
925 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
926 Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
927 }
928
6ff736d8 929 if (myFileHandle != INVALID_HANDLE_VALUE)
7fd59977 930
d9ff84e8 931 RAISE( "OSD_File :: Build (): incorrect call - file already opened" );
7fd59977 932
933 myMode = Mode;
934 myPath.SystemName ( fName );
935
936 if ( fName.IsEmpty () )
937
d9ff84e8 938 RAISE( "OSD_File :: Build (): incorrent call - no filename given" );
7fd59977 939
6ff736d8 940 myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_NEW );
7fd59977 941
6ff736d8 942 if (myFileHandle == INVALID_HANDLE_VALUE)
7fd59977 943
944 _osd_wnt_set_error ( myError, OSD_WFile );
945
946 else {
742cc8b0 947#ifndef OCCT_UWP
7fd59977 948 SetProtection ( Protect );
742cc8b0 949#else
950 (void)Protect;
951#endif
7fd59977 952 myIO |= FLAG_FILE;
953
954 } // end else
955
956} // end OSD_File :: Build
957
958
959
960// ---------------------------------------------------------------------
961// Open a file
962// ---------------------------------------------------------------------
963
302f96fb 964void OSD_File :: Open (const OSD_OpenMode Mode, const OSD_Protection& /*Protect*/)
965{
7fd59977 966
967 TCollection_AsciiString fName;
968
969
6ff736d8 970 if (myFileHandle != INVALID_HANDLE_VALUE)
7fd59977 971
d9ff84e8 972 RAISE( "OSD_File :: Open (): incorrect call - file already opened" );
7fd59977 973
974 myMode = Mode;
975 myPath.SystemName ( fName );
976
977 if ( fName.IsEmpty () )
978
d9ff84e8 979 RAISE( "OSD_File :: Open (): incorrent call - no filename given" );
7fd59977 980
6ff736d8 981 myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_OLD );
7fd59977 982
6ff736d8 983 if (myFileHandle == INVALID_HANDLE_VALUE) {
7fd59977 984
985 _osd_wnt_set_error ( myError, OSD_WFile );
986 }
987 else
988 {
6ff736d8 989 myIO |= _get_file_type ( fName.ToCString (), myFileHandle );
7fd59977 990 }
991} // end OSD_File :: Open
992
993// ---------------------------------------------------------------------
994// Append to an existing file
995// ---------------------------------------------------------------------
996
742cc8b0 997void OSD_File :: Append ( const OSD_OpenMode Mode, const OSD_Protection& Protect) {
7fd59977 998
999 BOOL fNew = FALSE;
1000 TCollection_AsciiString fName;
1001
6ff736d8 1002 if (myFileHandle != INVALID_HANDLE_VALUE)
7fd59977 1003
d9ff84e8 1004 RAISE( "OSD_File :: Append (): incorrect call - file already opened" );
7fd59977 1005
1006 myMode = Mode;
1007 myPath.SystemName ( fName );
1008
1009 if ( fName.IsEmpty () )
1010
d9ff84e8 1011 RAISE( "OSD_File :: Append (): incorrent call - no filename given" );
7fd59977 1012
6ff736d8 1013 myFileHandle = _open_file ( fName.ToCString (), Mode, OPEN_APPEND, &fNew );
7fd59977 1014
6ff736d8 1015 if (myFileHandle == INVALID_HANDLE_VALUE)
7fd59977 1016
1017 _osd_wnt_set_error ( myError, OSD_WFile );
1018
1019 else {
1020
1021 if ( !fNew ) {
1022
6ff736d8 1023 myIO |= _get_file_type ( fName.ToCString (), myFileHandle );
7fd59977 1024 Seek ( 0, OSD_FromEnd );
1025
1026 } else {
742cc8b0 1027#ifndef OCCT_UWP
1028 SetProtection ( Protect );
1029#else
1030 (void)Protect;
1031#endif
7fd59977 1032 myIO |= FLAG_FILE;
1033
1034 } // end else
1035
1036 } // end else;
1037
1038} // end OSD_File :: Append
1039
1040// ---------------------------------------------------------------------
1041// Read content of a file
1042// ---------------------------------------------------------------------
1043
1044void OSD_File :: Read (
1045 TCollection_AsciiString& Buffer, const Standard_Integer Nbyte
1046 ) {
1047
1048 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
0797d9d3 1049#ifdef OCCT_DEBUG
7fd59977 1050 cout << " OSD_File::Read : it is a directory " << endl;
63c629aa 1051#endif
7fd59977 1052 return ;
1053// Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1054 }
1055
1056 Standard_Integer NbyteRead;
7fd59977 1057
d9ff84e8 1058 TEST_RAISE( "Read" );
7fd59977 1059
7c65581d 1060 char* buff = new Standard_Character[ Nbyte + 1 ];
7fd59977 1061
1062 Read ( buff, Nbyte, NbyteRead );
1063
7c65581d 1064 buff[ NbyteRead ] = 0;
7fd59977 1065
1066 if ( NbyteRead != 0 )
1067
7c65581d 1068 Buffer = buff;
7fd59977 1069
1070 else
1071
1072 Buffer.Clear ();
1073
1074 delete [] buff;
1075
1076} // end OSD_File :: Read
1077
7fd59977 1078// ---------------------------------------------------------------------
1079// Read a line from a file
1080// ---------------------------------------------------------------------
1081
7fd59977 1082// Modified so that we have <nl> at end of line if we have read <nl> or <cr>
1083// in the file.
1084// by LD 17 dec 98 for B4.4
1085
1086void OSD_File :: ReadLine (
1087 TCollection_AsciiString& Buffer,
1088 const Standard_Integer NByte, Standard_Integer& NbyteRead
1089 ) {
1090
7fd59977 1091 DWORD dwBytesRead;
1092 DWORD dwDummy;
1093 Standard_Character peekChar;
1094 Standard_PCharacter ppeekChar;
1095 Standard_PCharacter cBuffer;
68299304 1096 LONG aSeekPos;
7fd59977 1097
1098 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
1099 Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1100 }
1101
d9ff84e8 1102 TEST_RAISE( "ReadLine" );
7fd59977 1103
1104 if ( myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE ) )
1105
d9ff84e8 1106 RAISE( "OSD_File :: ReadLine (): attempt to read from write only pipe" );
7fd59977 1107
1108 // +----> leave space for end-of-string
1109 // | plus <CR><LF> sequence
1110 // |
1111
1112 ppeekChar=&peekChar;
1113 cBuffer = new Standard_Character[ NByte + 3 ];
1114
1115 if ( myIO & FLAG_FILE ) {
1116
68299304 1117 if (!ReadFile (myFileHandle, cBuffer, NByte, &dwBytesRead, NULL)) { // an error occured
7fd59977 1118
1119 _osd_wnt_set_error ( myError, OSD_WFile );
1120 Buffer.Clear ();
1121 NbyteRead = 0;
1122
1123 } else if ( dwBytesRead == 0 ) { // end-of-file reached
1124
1125 Buffer.Clear ();
1126 NbyteRead = 0;
1127 myIO |= FLAG_EOF;
1128
1129 } else {
1130 myIO &= ~FLAG_EOF ; // if the file increased since last read (LD)
68299304 1131 NbyteRead = _get_line (cBuffer, dwBytesRead, aSeekPos);
7fd59977 1132
68299304 1133 if ( NbyteRead == -1 ) // last character in the buffer is <CR> -
1134 { // peek next character to see if it is a <LF>
6ff736d8 1135 if (!ReadFile (myFileHandle, ppeekChar, 1, &dwDummy, NULL)) {
7fd59977 1136
1137 _osd_wnt_set_error ( myError, OSD_WFile );
1138
1139 } else if ( dwDummy != 0 ) { // end-of-file reached ?
1140
742cc8b0 1141 if (peekChar != '\n') // if we did not get a <CR><LF> sequence
1142 {
1143 // adjust file position
c8c250a5 1144 LARGE_INTEGER aDistanceToMove;
742cc8b0 1145 aDistanceToMove.QuadPart = -1;
1146 SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
1147 }
7fd59977 1148 } else
1149 myIO |= FLAG_EOF;
1150
1151 NbyteRead = dwBytesRead;
1152
68299304 1153 } else if ( aSeekPos != 0 )
1154 {
c8c250a5 1155 LARGE_INTEGER aDistanceToMove;
742cc8b0 1156 aDistanceToMove.QuadPart = aSeekPos;
1157 SetFilePointerEx(myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
7fd59977 1158 }
1159
1160 } // end else
1161
1162 } else if ( myIO & FLAG_SOCKET || myIO & FLAG_PIPE || myIO & FLAG_NAMED_PIPE ) {
742cc8b0 1163#ifndef OCCT_UWP
6ff736d8 1164 dwBytesRead = (DWORD)_get_buffer (myFileHandle, cBuffer,
1165 (DWORD)NByte, TRUE, myIO & FLAG_SOCKET);
7fd59977 1166
1167 if ( ( int )dwBytesRead == -1 ) { // an error occured
1168
1169 _osd_wnt_set_error ( myError, OSD_WFile );
1170 Buffer.Clear ();
1171 NbyteRead = 0;
1172
1173 } else if ( dwBytesRead == 0 ) { // connection closed - set end-of-file flag
1174
1175 Buffer.Clear ();
1176 NbyteRead = 0;
1177 myIO |= FLAG_EOF;
1178
1179 } else {
1180
68299304 1181 NbyteRead = _get_line (cBuffer, dwBytesRead, aSeekPos);
7fd59977 1182
68299304 1183 if (NbyteRead == -1) // last character in the buffer is <CR> -
1184 { // peek next character to see if it is a <LF>
7fd59977 1185 NbyteRead = dwBytesRead; // (LD) always fits this case.
1186
6ff736d8 1187 dwDummy = _get_buffer (myFileHandle, ppeekChar, 1, TRUE, myIO & FLAG_SOCKET);
7fd59977 1188 if ( ( int )dwDummy == -1 ) { // an error occured
1189
1190 _osd_wnt_set_error ( myError, OSD_WFile );
1191
1192 } else if ( dwDummy != 0 ) { // connection closed ?
1193
1194 if ( peekChar == '\n' ) // we got a <CR><LF> sequence
1195
1196 dwBytesRead++ ; // (LD) we have to jump <LF>
1197 } else
1198
1199 myIO |= FLAG_EOF;
1200
68299304 1201 } else if (aSeekPos != 0)
1202 {
1203 dwBytesRead = dwBytesRead + aSeekPos;
7fd59977 1204 }
1205
1206 // Don't rewrite datas in cBuffer.
1207
1208 Standard_PCharacter cDummyBuffer = new Standard_Character[ NByte + 3 ];
1209
6ff736d8 1210 // remove pending input
1211 _get_buffer (myFileHandle, cDummyBuffer, dwBytesRead, FALSE, myIO & FLAG_SOCKET);
7fd59977 1212 delete [] cDummyBuffer ;
1213
1214 } // end else
742cc8b0 1215#endif
7fd59977 1216 } else
1217
d9ff84e8 1218 RAISE( "OSD_File :: ReadLine (): incorrect call - file is a directory" );
7fd59977 1219
1220 if ( !Failed () && !IsAtEnd () )
1221
1222 Buffer = cBuffer;
1223
1224 delete [] (Standard_PCharacter)cBuffer;
1225
1226} // end OSD_File :: ReadLine
1227
7fd59977 1228// --------------------------------------------------------------------------
1229// Read content of a file
1230// --------------------------------------------------------------------------
1231
1232void OSD_File :: Read (
7c65581d 1233 const Standard_Address Buffer,
7fd59977 1234 const Standard_Integer Nbyte, Standard_Integer& Readbyte
1235 ) {
1236
1237 DWORD dwBytesRead;
1238
1239 if ( OSD_File::KindOfFile ( ) == OSD_DIRECTORY ) {
1240 Standard_ProgramError::Raise("OSD_File::Read : it is a directory");
1241 }
1242
d9ff84e8 1243 TEST_RAISE( "Read" );
7fd59977 1244
1245 if ( myIO & FLAG_PIPE && !( myIO & FLAG_READ_PIPE ) )
1246
d9ff84e8 1247 RAISE( "OSD_File :: Read (): attempt to read from write only pipe" );
7fd59977 1248
6ff736d8 1249 if (!ReadFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesRead, NULL)) {
7fd59977 1250
1251 _osd_wnt_set_error ( myError, OSD_WFile );
1252 dwBytesRead = 0;
1253
1254 } else if ( dwBytesRead == 0 )
1255
1256 myIO |= FLAG_EOF;
1257
1258 else
1259
1260 myIO &= ~FLAG_EOF;
1261
1262 Readbyte = ( Standard_Integer )dwBytesRead;
1263
1264} // end OSD_File :: Read
1265
1266void OSD_File :: Write (
1267 const TCollection_AsciiString& Buffer,
1268 const Standard_Integer Nbyte
1269 ) {
1270
1271 Write ( ( Standard_Address )Buffer.ToCString (), Nbyte );
1272
1273} // end OSD_File :: Write
1274
1275// --------------------------------------------------------------------------
1276// Write content of a file
1277// --------------------------------------------------------------------------
1278
1279void OSD_File :: Write (
1280 const Standard_Address Buffer,
1281 const Standard_Integer Nbyte
1282 ) {
1283
1284 DWORD dwBytesWritten;
1285
d9ff84e8 1286 TEST_RAISE( "Write" );
7fd59977 1287
1288 if ( myIO & FLAG_PIPE && myIO & FLAG_READ_PIPE )
1289
d9ff84e8 1290 RAISE( "OSD_File :: Write (): attempt to write to read only pipe" );
7fd59977 1291
6ff736d8 1292 if (!WriteFile (myFileHandle, Buffer, (DWORD)Nbyte, &dwBytesWritten, NULL) ||
1293 dwBytesWritten != (DWORD)Nbyte)
7fd59977 1294
1295 _osd_wnt_set_error ( myError, OSD_WFile );
1296
1297} // end OSD_File :: Write
1298
1299void OSD_File :: Seek (
1300 const Standard_Integer Offset, const OSD_FromWhere Whence
1301 ) {
1302
302f96fb 1303 DWORD dwMoveMethod = 0;
7fd59977 1304
d9ff84e8 1305 TEST_RAISE( "Seek" );
7fd59977 1306
1307 if ( myIO & FLAG_FILE || myIO & FLAG_DIRECTORY ) {
1308
1309 switch ( Whence ) {
1310
1311 case OSD_FromBeginning:
1312
1313 dwMoveMethod = FILE_BEGIN;
1314
1315 break;
1316
1317 case OSD_FromHere:
1318
1319 dwMoveMethod = FILE_CURRENT;
1320
1321 break;
1322
1323 case OSD_FromEnd:
1324
1325 dwMoveMethod = FILE_END;
1326
1327 break;
1328
1329 default:
1330
d9ff84e8 1331 RAISE( "OSD_File :: Seek (): invalid parameter" );
7fd59977 1332
1333 } // end switch
c8c250a5 1334 LARGE_INTEGER aDistanceToMove, aNewFilePointer;
1335 aNewFilePointer.QuadPart = 0;
742cc8b0 1336 aDistanceToMove.QuadPart = Offset;
7fd59977 1337
742cc8b0 1338 if (!SetFilePointerEx(myFileHandle, aDistanceToMove, &aNewFilePointer, dwMoveMethod))
7fd59977 1339
1340 _osd_wnt_set_error ( myError, OSD_WFile );
1341
1342 } // end if
1343
1344 myIO &= ~FLAG_EOF;
1345
1346} // end OSD_File :: Seek
1347
1348// --------------------------------------------------------------------------
1349// Close a file
1350// --------------------------------------------------------------------------
1351
1352void OSD_File :: Close () {
1353
d9ff84e8 1354 TEST_RAISE( "Close" );
7fd59977 1355
6ff736d8 1356 CloseHandle (myFileHandle);
7fd59977 1357
6ff736d8 1358 myFileHandle = INVALID_HANDLE_VALUE;
7fd59977 1359 myIO = 0;
1360
1361} // end OSD_File :: Close
1362
1363// --------------------------------------------------------------------------
1364// Test if at end of file
1365// --------------------------------------------------------------------------
1366
1367Standard_Boolean OSD_File :: IsAtEnd () {
1368
d9ff84e8 1369 TEST_RAISE( "IsAtEnd" );
7fd59977 1370
1371 if (myIO & FLAG_EOF)
1372 return Standard_True ;
1373 return Standard_False ;
1374
1375} // end OSD_File :: IsAtEnd
1376
1377OSD_KindFile OSD_File :: KindOfFile () const {
1378
1379 OSD_KindFile retVal;
1380 Standard_Integer flags;
1381
6ff736d8 1382 if (myFileHandle == INVALID_HANDLE_VALUE) {
7fd59977 1383
1384 TCollection_AsciiString fName;
1385
1386 myPath.SystemName ( fName );
1387
1388 if ( fName.IsEmpty () )
1389
d9ff84e8 1390 RAISE( "OSD_File :: KindOfFile (): incorrent call - no filename given" );
7fd59977 1391
6ff736d8 1392 flags = _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE);
7fd59977 1393
1394 } else
1395
1396 flags = myIO;
1397
1398 switch ( flags & FLAG_TYPE ) {
1399
1400 case FLAG_FILE:
1401
1402 retVal = OSD_FILE;
1403
1404 break;
1405
1406 case FLAG_DIRECTORY:
1407
1408 retVal = OSD_DIRECTORY;
1409
1410 break;
1411
1412 case FLAG_SOCKET:
1413
1414 retVal = OSD_SOCKET;
1415
1416 break;
1417
1418 default:
1419
1420 retVal = OSD_UNKNOWN;
1421
1422 } // end switch
1423
1424 return retVal;
1425
1426} // end OSD_File :: KindOfFile
7fd59977 1427
7fd59977 1428//-------------------------------------------------debutpri???980424
1429
1430typedef struct _osd_wnt_key {
1431
1432 HKEY hKey;
ad03c234 1433 wchar_t* keyPath;
7fd59977 1434
1435 } OSD_WNT_KEY;
1436
1437
95e05159 1438 void OSD_File::BuildTemporary () {
7fd59977 1439
1440 OSD_Protection prt;
742cc8b0 1441 wchar_t tmpPath[ MAX_PATH ];
7fd59977 1442 BOOL fOK = FALSE;
742cc8b0 1443
1444// Windows Registry not supported by UWP
1445#ifndef OCCT_UWP
1446 HKEY hKey;
1447
7fd59977 1448 OSD_WNT_KEY regKey[ 2 ] = {
1449
1450 { HKEY_LOCAL_MACHINE,
ad03c234 1451 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
7fd59977 1452 },
1453 { HKEY_USERS,
ad03c234 1454 L".DEFAULT\\Environment"
7fd59977 1455 }
1456
1457 };
1458
1459 for ( int i = 0; i < 2; ++i ) {
1460
ad03c234 1461 if ( RegOpenKeyExW (
7fd59977 1462 regKey[ i ].hKey, regKey[ i ].keyPath, 0, KEY_QUERY_VALUE, &hKey
1463 ) == ERROR_SUCCESS
1464 ) {
1465
1466 DWORD dwType;
1467 DWORD dwSize = 0;
1468
742cc8b0 1469 if ( RegQueryValueExW (
1470 hKey, L"TEMP", NULL, &dwType, NULL, &dwSize
7fd59977 1471 ) == ERROR_SUCCESS
1472 ) {
1473
742cc8b0 1474 wchar_t* kVal = (wchar_t*)HeapAlloc (
7fd59977 1475 GetProcessHeap (), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
742cc8b0 1476 dwSize + sizeof (wchar_t)
7fd59977 1477 );
1478
742cc8b0 1479 RegQueryValueExW ( hKey, L"TEMP", NULL, &dwType, ( LPBYTE )kVal, &dwSize );
7fd59977 1480
1481 if ( dwType == REG_EXPAND_SZ )
1482
742cc8b0 1483 ExpandEnvironmentStringsW ( kVal, tmpPath, MAX_PATH );
7fd59977 1484
1485 else
1486
742cc8b0 1487 StringCchCopyW (tmpPath, _countof(tmpPath), kVal);
7fd59977 1488
1489 HeapFree ( GetProcessHeap (), 0, ( LPVOID )kVal );
1490 fOK = TRUE;
1491
1492 } // end if
1493
1494 RegCloseKey ( hKey );
1495
1496 } // end if
1497
1498 if ( fOK ) break;
1499
1500 } // end for
742cc8b0 1501#else
1502 if (GetTempPathW(_countof(tmpPath), tmpPath))
1503 fOK = TRUE;
1504#endif
1505 if ( !fOK ) StringCchCopyW(tmpPath, _countof(tmpPath), L"./");
7fd59977 1506
742cc8b0 1507 GetTempFileNameW ( tmpPath, L"CSF", 0, tmpPath );
7fd59977 1508
95e05159 1509 if ( IsOpen() )
1510 Close();
7fd59977 1511
742cc8b0 1512 char tmpPathA[MAX_PATH];
1513 WideCharToMultiByte(CP_UTF8, 0, tmpPath, -1, tmpPathA, sizeof(tmpPathA), NULL, NULL);
1514 SetPath(OSD_Path(tmpPathA));
1515
95e05159 1516 Build ( OSD_ReadWrite, prt );
7fd59977 1517} // end OSD_File :: BuildTemporary
1518
7fd59977 1519//-------------------------------------------------finpri???980424
1520
1521#if defined(__CYGWIN32__) || defined(__MINGW32__)
1522#define __try
1523#define __finally
1524#define __leave return
1525#endif
1526
1527void OSD_File :: SetLock ( const OSD_LockType Lock ) {
1528
1529 DWORD dwFlags;
1530 OVERLAPPED ovlp;
1531
d9ff84e8 1532 TEST_RAISE( "SetLock" );
7fd59977 1533
1534 ZeroMemory ( &ovlp, sizeof ( OVERLAPPED ) );
1535
1536 __try {
1537
1538 if ( ( myLock = Lock ) == OSD_NoLock ) {
1539
1540 UnLock ();
1541 __leave;
1542
1543 } else if ( myLock == OSD_ReadLock || myLock == OSD_ExclusiveLock ) {
1544
1545 dwFlags = LOCKFILE_EXCLUSIVE_LOCK;
1546
1547 } else
1548
1549 dwFlags = 0;
1550
6ff736d8 1551 LARGE_INTEGER aSize;
1552 aSize.QuadPart = Size();
1553 if (!LockFileEx (myFileHandle, dwFlags, 0, aSize.LowPart, aSize.HighPart, &ovlp)) {
7fd59977 1554
1555 _osd_wnt_set_error ( myError, OSD_WFile );
1556 __leave;
1557
1558 } // end if
1559
1560 ImperativeFlag = Standard_True;
1561
1562 } // end __try
1563
1564 __finally {}
1565
1566#ifdef VAC
1567leave: ; // added for VisualAge
1568#endif
1569} // end OSD_File :: SetLock
1570
1571#if defined(__CYGWIN32__) || defined(__MINGW32__)
1572#undef __try
1573#undef __finally
1574#undef __leave
1575#endif
1576
1577void OSD_File :: UnLock () {
1578
d9ff84e8 1579 TEST_RAISE( "Unlock" );
7fd59977 1580
1581 if ( ImperativeFlag ) {
1582
6ff736d8 1583 LARGE_INTEGER aSize;
1584 aSize.QuadPart = Size();
742cc8b0 1585
1586 OVERLAPPED anOverlappedArea;
1587 anOverlappedArea.Offset = 0;
1588 anOverlappedArea.OffsetHigh = 0;
1589
1590 if (!UnlockFileEx(myFileHandle, 0, aSize.LowPart, aSize.HighPart,&anOverlappedArea))
7fd59977 1591 _osd_wnt_set_error ( myError, OSD_WFile );
1592
1593 ImperativeFlag = Standard_False;
1594
1595 } // end if
1596
1597} // end OSD_File :: UnLock
1598
1599OSD_LockType OSD_File :: GetLock () {
1600
1601 return myLock;
1602
1603} // end OSD_File :: GetLock
1604
1605Standard_Boolean OSD_File :: IsLocked () {
1606
d9ff84e8 1607 TEST_RAISE( "IsLocked" );
7fd59977 1608
1609 return ImperativeFlag;
1610
1611} // end OSD_File :: IsLocked
1612
1613
1614// --------------------------------------------------------------------------
1615// Return size of a file
1616// --------------------------------------------------------------------------
1617
7c65581d 1618Standard_Size OSD_File::Size()
1619{
1620 TEST_RAISE("Size");
1621#if (_WIN32_WINNT >= 0x0500)
1622 LARGE_INTEGER aSize;
1623 aSize.QuadPart = 0;
1624 if (GetFileSizeEx (myFileHandle, &aSize) == 0)
1625 {
1626 _osd_wnt_set_error (myError, OSD_WFile);
1627 }
1628 return (Standard_Size)aSize.QuadPart;
1629#else
1630 DWORD aSize = GetFileSize (myFileHandle, NULL);
1631 if (aSize == INVALID_FILE_SIZE)
1632 {
1633 _osd_wnt_set_error (myError, OSD_WFile);
1634 }
1635 return aSize;
1636#endif
1637}
7fd59977 1638
7fd59977 1639// --------------------------------------------------------------------------
1640// Test if a file is open
1641// --------------------------------------------------------------------------
1642
1643Standard_Boolean OSD_File :: IsOpen () const {
1644
6ff736d8 1645 return myFileHandle != INVALID_HANDLE_VALUE;
7fd59977 1646
1647} // end OSD_File :: IsOpen
1648
1649#if defined(__CYGWIN32__) || defined(__MINGW32__)
1650#define __try
1651#define __finally
1652#define __leave return retVal
1653#endif
1654
742cc8b0 1655#ifndef OCCT_UWP
7fd59977 1656PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd (
fb0b0531 1657 const OSD_Protection& prot, BOOL fDir, const wchar_t* fName
7fd59977 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;
7c65581d 1673// DWORD dwAccessGroupDir;
7fd59977 1674 DWORD dwAccessOwnerDir;
7c65581d 1675// DWORD dwAccessWorldDir;
7fd59977 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;
302f96fb 1681 PSECURITY_DESCRIPTOR retVal = NULL;
7fd59977 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
1714retry:
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 () );
7c65581d 1741// dwAccessGroupDir = _get_dir_access_mask ( prot.Group () );
7fd59977 1742 dwAccessOwnerDir = _get_dir_access_mask ( prot.User () );
7c65581d 1743// dwAccessWorldDir = _get_dir_access_mask ( prot.World () );
7fd59977 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
1908leave: ; // added for VisualAge
1909#endif
1910
1911 return retVal;
1912
1913} // end _osd_wnt_protection_to_sd */
742cc8b0 1914#endif
7fd59977 1915
1916#if defined(__CYGWIN32__) || defined(__MINGW32__)
1917#undef __try
1918#undef __finally
1919#undef __leave
1920#endif
1921
6ff736d8 1922static void __fastcall _test_raise ( HANDLE hFile, Standard_CString str ) {
7fd59977 1923
742cc8b0 1924 if (hFile == INVALID_HANDLE_VALUE) {
1925 TCollection_AsciiString buff = "OSD_File :: ";
1926 buff += str;
1927 buff += " (): wrong access";
7fd59977 1928
742cc8b0 1929 Standard_ProgramError::Raise(buff.ToCString());
1930 } // end if
7fd59977 1931
1932} // end _test_raise
1933
68299304 1934// Returns number of bytes in the string (including end \n, but excluding \r);
1935//
1936static Standard_Integer __fastcall _get_line (Standard_PCharacter& buffer, DWORD dwBuffSize, LONG& theSeekPos)
1937{
7fd59977 1938
7fd59977 1939 Standard_PCharacter ptr;
1940
1941 buffer[ dwBuffSize ] = 0;
1942 ptr = buffer;
1943
1944 while ( *ptr != 0 ) {
1945
68299304 1946 if ( *ptr == '\n' )
1947 {
1948 ptr++ ; // jump newline char.
1949 *ptr = 0 ;
1950 theSeekPos = (LONG)(ptr - buffer - dwBuffSize);
1951 return (Standard_Integer)(ptr - buffer);
1952 }
1953 else if ( *ptr == '\r' && ptr[ 1 ] == '\n' )
1954 {
1955 *(ptr++) = '\n' ; // Substitue carriage return by newline.
1956 *ptr = 0 ;
1957 theSeekPos = (LONG)(ptr + 1 - buffer - dwBuffSize);
1958 return (Standard_Integer)(ptr - buffer);
1959 }
1960 else if ( *ptr == '\r' && ptr[ 1 ] == 0 ) {
7fd59977 1961 *ptr = '\n' ; // Substitue carriage return by newline
68299304 1962 return -1;
7fd59977 1963 }
1964 ++ptr;
1965
1966 } // end while
1967
68299304 1968 theSeekPos = 0;
1969 return dwBuffSize;
7fd59977 1970} // end _get_line
1971
742cc8b0 1972#ifndef OCCT_UWP
7fd59977 1973static int __fastcall _get_buffer (
1974 HANDLE hChannel,
1975 Standard_PCharacter& buffer,
1976 DWORD dwSize,
1977 BOOL fPeek, BOOL fSocket
1978 ) {
1979
1980 int retVal = -1;
1981 int flags;
1982 DWORD dwDummy;
1983 DWORD dwBytesRead;
1984
1985 if ( fSocket ) {
1986
1987 flags = fPeek ? MSG_PEEK : 0;
1988
1989 retVal = recv ( ( SOCKET )hChannel, buffer, ( int )dwSize, flags );
1990
1991 if ( retVal == SOCKET_ERROR ) retVal = -1;
1992
1993 } else {
1994
1995 if ( fPeek ) {
1996
1997 if ( !PeekNamedPipe (
1998 hChannel, buffer, dwSize, &dwBytesRead, &dwDummy, &dwDummy
1999 ) && GetLastError () != ERROR_BROKEN_PIPE
2000 )
2001
2002 retVal = -1;
2003
2004 else
2005
2006 retVal = ( int )dwBytesRead;
2007
2008 } else {
2009
2010 if ( !ReadFile ( hChannel, buffer, dwSize, &dwBytesRead, NULL ) )
2011
2012 retVal = -1;
2013
2014 else
2015
2016 retVal = ( int )dwBytesRead;
2017
2018 } // end else
2019
2020 } // end else
2021
2022 return retVal;
2023
2024} // end _get_buffer
2025
2026
2027static DWORD __fastcall _get_access_mask ( OSD_SingleProtection prt ) {
2028
302f96fb 2029 DWORD retVal = 0;
7fd59977 2030
2031 switch ( prt ) {
2032
2033 case OSD_None:
2034
2035 retVal = 0;
2036
2037 break;
2038
2039 case OSD_R:
2040
2041 retVal = FILE_GENERIC_READ;
2042
2043 break;
2044
2045 case OSD_W:
2046
2047 retVal = FILE_GENERIC_WRITE;
2048
2049 break;
2050
2051 case OSD_RW:
2052
2053 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
2054
2055 break;
2056
2057 case OSD_X:
2058
2059 retVal = FILE_GENERIC_EXECUTE;
2060
2061 break;
2062
2063 case OSD_RX:
2064
2065 retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
2066
2067 break;
2068
2069 case OSD_WX:
2070
2071 retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2072
2073 break;
2074
2075 case OSD_RWX:
2076
2077 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
2078
2079 break;
2080
2081 case OSD_D:
2082
2083 retVal = DELETE;
2084
2085 break;
2086
2087 case OSD_RD:
2088
2089 retVal = FILE_GENERIC_READ | DELETE;
2090
2091 break;
2092
2093 case OSD_WD:
2094
2095 retVal = FILE_GENERIC_WRITE | DELETE;
2096
2097 break;
2098
2099 case OSD_RWD:
2100
2101 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
2102
2103 break;
2104
2105 case OSD_XD:
2106
2107 retVal = FILE_GENERIC_EXECUTE | DELETE;
2108
2109 break;
2110
2111 case OSD_RXD:
2112
2113 retVal = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE;
2114
2115 break;
2116
2117 case OSD_WXD:
2118
2119 retVal = FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2120
2121 break;
2122
2123 case OSD_RWXD:
2124
2125 retVal = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
2126
2127 break;
2128
2129 default:
2130
d9ff84e8 2131 RAISE( "_get_access_mask (): incorrect parameter" );
7fd59977 2132
2133 } // end switch
2134
2135 return retVal;
2136
2137} // end _get_access_mask
2138
2139static DWORD __fastcall _get_dir_access_mask ( OSD_SingleProtection prt ) {
2140
302f96fb 2141 DWORD retVal = 0;
7fd59977 2142
2143 switch ( prt ) {
2144
2145 case OSD_None:
2146
2147 retVal = 0;
2148
2149 break;
2150
2151 case OSD_R:
2152
2153 retVal = GENERIC_READ;
2154
2155 break;
2156
2157 case OSD_W:
2158
2159 retVal = GENERIC_WRITE;
2160
2161 break;
2162
2163 case OSD_RW:
2164
2165 retVal = GENERIC_READ | GENERIC_WRITE;
2166
2167 break;
2168
2169 case OSD_X:
2170
2171 retVal = GENERIC_EXECUTE;
2172
2173 break;
2174
2175 case OSD_RX:
2176
2177 retVal = GENERIC_READ | GENERIC_EXECUTE;
2178
2179 break;
2180
2181 case OSD_WX:
2182
2183 retVal = GENERIC_WRITE | GENERIC_EXECUTE;
2184
2185 break;
2186
2187 case OSD_RWX:
2188
2189 retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE;
2190
2191 break;
2192
2193 case OSD_D:
2194
2195 retVal = DELETE;
2196
2197 break;
2198
2199 case OSD_RD:
2200
2201 retVal = GENERIC_READ | DELETE;
2202
2203 break;
2204
2205 case OSD_WD:
2206
2207 retVal = GENERIC_WRITE | DELETE;
2208
2209 break;
2210
2211 case OSD_RWD:
2212
2213 retVal = GENERIC_READ | GENERIC_WRITE | DELETE;
2214
2215 break;
2216
2217 case OSD_XD:
2218
2219 retVal = GENERIC_EXECUTE | DELETE;
2220
2221 break;
2222
2223 case OSD_RXD:
2224
2225 retVal = GENERIC_READ | GENERIC_EXECUTE | DELETE;
2226
2227 break;
2228
2229 case OSD_WXD:
2230
2231 retVal = GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2232
2233 break;
2234
2235 case OSD_RWXD:
2236
2237 retVal = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
2238
2239 break;
2240
2241 default:
2242
d9ff84e8 2243 RAISE( "_get_dir_access_mask (): incorrect parameter" );
7fd59977 2244
2245 } // end switch
2246
2247 return retVal;
2248
2249} // end _get_dir_access_mask
742cc8b0 2250#endif
7fd59977 2251static HANDLE __fastcall _open_file (
2252 Standard_CString fName,
2253 OSD_OpenMode oMode,
2254 DWORD dwOptions, LPBOOL fNew
2255 ) {
2256
2257 HANDLE retVal = INVALID_HANDLE_VALUE;
302f96fb 2258 DWORD dwDesiredAccess = 0;
7fd59977 2259 DWORD dwCreationDistribution;
2260
2261 switch ( oMode ) {
2262
2263 case OSD_ReadOnly:
2264
2265 dwDesiredAccess = GENERIC_READ;
2266
2267 break;
2268
2269 case OSD_WriteOnly:
2270
2271 dwDesiredAccess = GENERIC_WRITE;
2272
2273 break;
2274
2275 case OSD_ReadWrite:
2276
2277 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
2278
2279 break;
2280
2281 default:
2282
d9ff84e8 2283 RAISE( "_open_file (): incorrect parameter" );
7fd59977 2284
2285 } // end switch
2286
2287 dwCreationDistribution = ( dwOptions != OPEN_NEW ) ? OPEN_EXISTING : CREATE_ALWAYS;
2288
d9ff84e8 2289 // make wide character string from UTF-8
2290 TCollection_ExtendedString fNameW(fName, Standard_True);
742cc8b0 2291#ifndef OCCT_UWP
d9ff84e8 2292 retVal = CreateFileW (
fb0b0531 2293 fNameW.ToWideString(), dwDesiredAccess,
7fd59977 2294 FILE_SHARE_READ | FILE_SHARE_WRITE,
2295 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2296 );
742cc8b0 2297#else
2298 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams = {};
2299 pCreateExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
2300 pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
2301 pCreateExParams.lpSecurityAttributes = NULL;
2302 pCreateExParams.hTemplateFile = NULL;
2303 retVal = CreateFile2 (
fb0b0531 2304 fNameW.ToWideString(), dwDesiredAccess,
742cc8b0 2305 FILE_SHARE_READ | FILE_SHARE_WRITE,
2306 dwCreationDistribution, &pCreateExParams
2307 );
2308#endif
7fd59977 2309 if ( retVal == INVALID_HANDLE_VALUE &&
2310 dwOptions == OPEN_APPEND &&
2311 GetLastError () == ERROR_FILE_NOT_FOUND
2312 ) {
2313
2314
2315 dwCreationDistribution = CREATE_ALWAYS;
742cc8b0 2316#ifndef OCCT_UWP
d9ff84e8 2317 retVal = CreateFileW (
fb0b0531 2318 fNameW.ToWideString(), dwDesiredAccess,
7fd59977 2319 FILE_SHARE_READ | FILE_SHARE_WRITE,
2320 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
2321 );
742cc8b0 2322#else
2323 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams2 = {};
2324 pCreateExParams2.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
2325 pCreateExParams2.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
2326 pCreateExParams2.lpSecurityAttributes = NULL;
2327 pCreateExParams2.hTemplateFile = NULL;
2328 retVal = CreateFile2(
fb0b0531 2329 fNameW.ToWideString(), dwDesiredAccess,
742cc8b0 2330 FILE_SHARE_READ | FILE_SHARE_WRITE,
2331 dwCreationDistribution, &pCreateExParams2
2332 );
2333#endif
7fd59977 2334
2335 *fNew = TRUE;
2336
2337 } // end if
2338
2339 return retVal;
2340
2341} // end _open_file
2342
2343Standard_Integer __fastcall _get_file_type (
6ff736d8 2344 Standard_CString fName, HANDLE fileHandle
7fd59977 2345 ) {
2346
302f96fb 2347 Standard_Integer retVal = 0;
7fd59977 2348 int fileType;
2349
6ff736d8 2350 fileType = (fileHandle == INVALID_HANDLE_VALUE ?
2351 FILE_TYPE_DISK : GetFileType (fileHandle));
7fd59977 2352
2353 switch ( fileType ) {
2354
2355 case FILE_TYPE_UNKNOWN:
2356
2357 retVal = FLAG_SOCKET;
2358
2359 break;
2360
2361 case FILE_TYPE_DISK:
d9ff84e8 2362 {
2363 // make wide character string from UTF-8
2364 TCollection_ExtendedString fNameW(fName, Standard_True);
7fd59977 2365
742cc8b0 2366 WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
fb0b0531 2367 if (GetFileAttributesExW (fNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
742cc8b0 2368
2369 retVal = aFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FLAG_DIRECTORY : FLAG_FILE;
7fd59977 2370
2371 else
2372
2373 retVal = 0x80000000;
d9ff84e8 2374 }
7fd59977 2375 break;
2376
2377 case FILE_TYPE_CHAR:
2378
2379 retVal = FLAG_DEVICE;
2380
2381 break;
2382
2383 case FILE_TYPE_PIPE:
2384
2385 retVal = FLAG_PIPE;
2386
2387 break;
2388
2389 } // end switch
2390
2391 return retVal;
2392
2393} // end _get_file_type
2394
2395#if defined(__CYGWIN32__) || defined(__MINGW32__)
2396#define __try
2397#define __finally
2398#define __leave return retVal
2399#endif
2400
742cc8b0 2401#ifndef OCCT_UWP
2402// None of the existing security APIs are supported in a UWP applications
7fd59977 2403BOOL __fastcall _osd_wnt_sd_to_protection (
2404 PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL fDir
2405 ) {
2406
2407 int i;
2408 BOOL fPresent;
2409 BOOL fDefaulted;
2410 PACL pACL;
2411 PSID pSIDowner;
2412 PSID pSIDadmin;
2413 PSID pSIDworld;
2414 LPVOID pACE;
2415 DWORD dwAccessOwner = 0;
2416 DWORD dwAccessGroup = 0;
2417 DWORD dwAccessAdmin = 0;
2418 DWORD dwAccessWorld = 0;
2419 BOOL retVal = FALSE;
2420 GET_PROT_FUNC _get_prot_func = fDir ? &_get_protection_dir : &_get_protection;
2421
2422 __try {
2423
2424 if ( !GetSecurityDescriptorOwner ( pSD, &pSIDowner, &fDefaulted ) ) __leave;
2425
2426 if ( !GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDefaulted ) ||
2427 !fPresent
2428 ) __leave;
2429
2430 if ( pSIDowner == NULL || pACL == NULL ) {
2431
2432 SetLastError ( ERROR_NO_SECURITY_ON_OBJECT );
2433 __leave;
2434
2435 } // end if
2436
2437 pSIDadmin = AdminSid ();
2438 pSIDworld = WorldSid ();
2439
2440 for ( i = 0; i < ( int )pACL -> AceCount; ++i ) {
2441
2442 if ( GetAce ( pACL, i, &pACE ) ) {
2443
2444 if ( EqualSid ( pSIDowner, GET_SID( pACE ) ) )
2445
2446 dwAccessOwner = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2447 0 : *GET_MSK( pACE );
2448
2449 else if ( EqualSid ( pSIDadmin, GET_SID( pACE ) ) )
2450
2451 dwAccessAdmin = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2452 0 : *GET_MSK( pACE );
2453
2454 else if ( EqualSid ( pSIDworld, GET_SID( pACE ) ) )
2455
2456 dwAccessWorld = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2457 0 : *GET_MSK( pACE );
2458
2459 else
2460
2461 dwAccessGroup = ( ( PACE_HEADER )pACE ) -> AceType == ACCESS_DENIED_ACE_TYPE ?
2462 0 : *GET_MSK( pACE );
2463
2464 } // end if
2465
2466 } // end for
2467
2468 prot.SetValues (
2469 ( *_get_prot_func ) ( dwAccessAdmin ),
2470 ( *_get_prot_func ) ( dwAccessOwner ),
2471 ( *_get_prot_func ) ( dwAccessGroup ),
2472 ( *_get_prot_func ) ( dwAccessWorld )
2473 );
2474
2475 retVal = TRUE;
2476
2477 } // end __try
2478
2479 __finally {}
2480
2481#ifdef VAC
2482leave: ; // added for VisualAge
2483#endif
2484
2485 return retVal;
2486
2487} // end _osd_wnt_sd_to_protection
742cc8b0 2488#endif
7fd59977 2489
2490#if defined(__CYGWIN32__) || defined(__MINGW32__)
2491#undef __try
2492#undef __finally
2493#undef __leave
2494#endif
742cc8b0 2495#ifndef OCCT_UWP
7fd59977 2496static OSD_SingleProtection __fastcall _get_protection ( DWORD mask ) {
2497
2498 OSD_SingleProtection retVal;
2499
2500 switch ( mask ) {
2501
2502 case FILE_GENERIC_READ:
2503
2504 retVal = OSD_R;
2505
2506 break;
2507
2508 case FILE_GENERIC_WRITE:
2509
2510 retVal = OSD_W;
2511
2512 break;
2513
2514 case FILE_GENERIC_READ | FILE_GENERIC_WRITE:
2515
2516 retVal = OSD_RW;
2517
2518 break;
2519
2520 case FILE_GENERIC_EXECUTE:
2521
2522 retVal = OSD_X;
2523
2524 break;
2525
2526 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE:
2527
2528 retVal = OSD_RX;
2529
2530 break;
2531
2532 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2533
2534 retVal = OSD_WX;
2535
2536 break;
2537
2538 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
2539
2540 retVal = OSD_RWX;
2541
2542 break;
2543
2544 case DELETE:
2545
2546 retVal = OSD_D;
2547
2548 break;
2549
2550 case FILE_GENERIC_READ | DELETE:
2551
2552 retVal = OSD_RD;
2553
2554 break;
2555
2556 case FILE_GENERIC_WRITE | DELETE:
2557
2558 retVal = OSD_WD;
2559
2560 break;
2561
2562 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE:
2563
2564 retVal = OSD_RWD;
2565
2566 break;
2567
2568 case FILE_GENERIC_EXECUTE | DELETE:
2569
2570 retVal = OSD_XD;
2571
2572 break;
2573
2574 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE:
2575
2576 retVal = OSD_RXD;
2577
2578 break;
2579
2580 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2581
2582 retVal = OSD_WXD;
2583
2584 break;
2585
2586 case FILE_ALL_ACCESS:
2587 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
2588
2589 retVal = OSD_RWXD;
2590
2591 break;
2592
2593 case 0:
2594 default:
2595
2596 retVal = OSD_None;
2597
2598 } // end switch
2599
2600 return retVal;
2601
2602} // end _get_protection
2603
2604static OSD_SingleProtection __fastcall _get_protection_dir ( DWORD mask ) {
2605
2606 OSD_SingleProtection retVal;
2607
2608 switch ( mask ) {
2609
2610 case GENERIC_READ:
2611
2612 retVal = OSD_R;
2613
2614 break;
2615
2616 case GENERIC_WRITE:
2617
2618 retVal = OSD_W;
2619
2620 break;
2621
2622 case GENERIC_READ | GENERIC_WRITE:
2623
2624 retVal = OSD_RW;
2625
2626 break;
2627
2628 case GENERIC_EXECUTE:
2629
2630 retVal = OSD_X;
2631
2632 break;
2633
2634 case GENERIC_READ | GENERIC_EXECUTE:
2635
2636 retVal = OSD_RX;
2637
2638 break;
2639
2640 case GENERIC_WRITE | GENERIC_EXECUTE:
2641
2642 retVal = OSD_WX;
2643
2644 break;
2645
2646 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE:
2647
2648 retVal = OSD_RWX;
2649
2650 break;
2651
2652 case DELETE:
2653
2654 retVal = OSD_D;
2655
2656 break;
2657
2658 case GENERIC_READ | DELETE:
2659
2660 retVal = OSD_RD;
2661
2662 break;
2663
2664 case GENERIC_WRITE | DELETE:
2665
2666 retVal = OSD_WD;
2667
2668 break;
2669
2670 case GENERIC_READ | GENERIC_WRITE | DELETE:
2671
2672 retVal = OSD_RWD;
2673
2674 break;
2675
2676 case GENERIC_EXECUTE | DELETE:
2677
2678 retVal = OSD_XD;
2679
2680 break;
2681
2682 case GENERIC_READ | GENERIC_EXECUTE | DELETE:
2683
2684 retVal = OSD_RXD;
2685
2686 break;
2687
2688 case GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2689
2690 retVal = OSD_WXD;
2691
2692 break;
2693
2694 case FILE_ALL_ACCESS:
2695 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
2696
2697 retVal = OSD_RWXD;
2698
2699 break;
2700
2701 case 0:
2702 default:
2703
2704 retVal = OSD_None;
2705
2706 } // end switch
2707
2708 return retVal;
2709
2710} // end _get_protection_dir
742cc8b0 2711#endif
7fd59977 2712
7fd59977 2713Standard_Boolean OSD_File::IsReadable()
2714{
2715 TCollection_AsciiString FileName ;
2716 HANDLE Channel ;
2717
2718 myPath.SystemName(FileName) ;
2719 Channel = _open_file(FileName.ToCString(), OSD_ReadOnly, OPEN_OLD) ;
2720 if (Channel == INVALID_HANDLE_VALUE)
2721 return Standard_False ;
2722 else {
2723 CloseHandle (Channel) ;
2724 return Standard_True ;
2725 }
2726}
2727
2728
2729Standard_Boolean OSD_File::IsWriteable()
2730{
2731 TCollection_AsciiString FileName ;
2732 HANDLE Channel ;
2733
2734 myPath.SystemName(FileName) ;
2735 Channel = _open_file(FileName.ToCString(), OSD_ReadWrite, OPEN_OLD) ;
2736 if (Channel == INVALID_HANDLE_VALUE)
2737 return Standard_False ;
2738 else {
2739 CloseHandle (Channel) ;
2740 return Standard_True ;
2741 }
2742}
2743
2744Standard_Boolean OSD_File::IsExecutable()
2745{
2746 return IsReadable() ;
2747
2748// if (_access(FileName.ToCString(),0))
2749}
2750
6ff736d8 2751#endif /* _WIN32 */
7fd59977 2752
4485f3d0 2753// ---------------------------------------------------------------------
2754// Destructs a file object (unlocks and closes file if it is open)
2755// ---------------------------------------------------------------------
2756
2757OSD_File::~OSD_File()
2758{
2759 if (IsOpen())
2760 {
2761 if (IsLocked())
2762 UnLock();
2763 Close();
2764 }
2765}
7fd59977 2766
2767// ---------------------------------------------------------------------
2768// Read lines in a file while it is increasing.
2769// Each line is terminated with a <nl>.
2770// ---------------------------------------------------------------------
2771
2772#include <OSD.hxx>
2773
2774Standard_Boolean OSD_File::ReadLastLine(TCollection_AsciiString& aLine,const Standard_Integer aDelay,const Standard_Integer aNbTries)
2775{
2776 static Standard_Integer MaxLength = 1000 ;
2777 Standard_Integer Len ;
2778 Standard_Integer Count = aNbTries ;
2779
2780 if (Count <= 0)
2781 return Standard_False ;
302f96fb 2782 for(;;) {
7fd59977 2783 ReadLine(aLine, MaxLength, Len) ;
2784 if (!aLine.IsEmpty())
2785 return Standard_True ;
2786 if (!--Count)
2787 return Standard_False ;
2788 OSD::SecSleep(aDelay) ;
2789 }
2790}
2791
2792
2793Standard_Boolean OSD_File::Edit()
2794{
2795 cout << "Function OSD_File::Edit() not yet implemented." << endl;
2796 return Standard_False ;
2797}
2798
2799
2800