0023947: Eliminate trivial compiler warnings in MSVC++ with warning level 4
[occt.git] / src / OSD / OSD_FileNode.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #ifndef WNT
24
25 #include <unistd.h>
26 #include <errno.h>
27 #include <string.h>
28
29 #include <Standard_ProgramError.hxx>
30 #include <OSD_OSDError.hxx>
31 #include <Standard_NullObject.hxx>
32 #include <OSD_WhoAmI.hxx>
33 #include <OSD_FileNode.ixx>
34
35 #if!defined(TM_IN_SYS_TIME) && defined(HAVE_TIME_H)
36 # include <time.h>
37 #elif HAVE_SYS_TIME_H
38 # include <sys/time.h>
39 #endif
40
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
43 #endif
44
45 #ifdef HAVE_SYS_STAT_H
46 # include <sys/stat.h>  // for "stat"
47 #endif
48
49 #include <stdlib.h>    // For "system"
50 #include <errno.h>
51 #include <fcntl.h>
52
53 #ifdef HAVE_UNISTD_H
54 # include <unistd.h>
55 #endif
56
57 #include <stdio.h>
58
59 #ifdef HAVE_OSFCN_H
60 # include <osfcn.h>
61 #endif
62
63
64 const OSD_WhoAmI Iam = OSD_WFileNode;
65
66
67 // Create a file/directory object
68
69 OSD_FileNode::OSD_FileNode (){
70  myFileChannel = -1;
71 }
72
73
74
75 // Create and initialize a file/directory object
76
77 OSD_FileNode::OSD_FileNode (const OSD_Path& Name){
78  SetPath (Name);
79 }
80
81
82
83 // Get values of object
84
85 void OSD_FileNode::Path (OSD_Path& Name)const{
86  Name = myPath;
87 }
88
89
90
91
92 // Set values of object
93
94 void OSD_FileNode::SetPath (const OSD_Path& Name){
95  myError.Reset();
96  myPath = Name;
97 }
98
99
100
101
102 // Test if specified file/directory exists
103  
104 Standard_Boolean  OSD_FileNode::Exists(){
105 int status;
106
107
108 // if (myPath.Name().Length()==0)  A directory can have a null name field (ex: root)
109 //  OSD_OSDError::Raise("OSD_FileNode::Exists : no name was given"); (LD)
110
111 // if (Failed()) Perror();
112
113  TCollection_AsciiString aBuffer;
114  myPath.SystemName ( aBuffer );
115  status = access ( aBuffer.ToCString() , F_OK );
116  
117  if (status == 0) return (Standard_True);
118    else return ( Standard_False );
119 }
120
121
122
123
124 // Physically remove a file/directory
125
126 void  OSD_FileNode::Remove(){
127
128 // if (myPath.Name().Length()==0) A directory can have a null name field (ex: root)
129 //  OSD_OSDError::Raise("OSD_FileNode::Remove : no name was given"); (LD)
130
131 // if (Failed()) Perror();
132
133  TCollection_AsciiString aBuffer;
134  myPath.SystemName ( aBuffer );
135
136  if(access(aBuffer.ToCString(), W_OK))
137    {
138      myError.SetValue (errno, Iam, "Remove");
139      return;
140    }
141
142  struct stat  stat_buf;
143
144  if(stat(aBuffer.ToCString(), &stat_buf))
145    {
146      myError.SetValue (errno, Iam, "Remove");
147      return;
148    }
149   
150  if (  S_ISDIR(stat_buf.st_mode))  {
151    // DIRECTORY
152
153    if(rmdir(aBuffer.ToCString()))
154      {
155        myError.SetValue (errno, Iam, "Remove");
156        return;
157      }
158    return; 
159
160  }
161  else if  (  S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode) ||
162              S_ISFIFO(stat_buf.st_mode)   )  { 
163    
164    if (unlink ( aBuffer.ToCString()) == -1) 
165      myError.SetValue (errno, Iam, "Remove");
166    return;
167  }
168  myError.SetValue (EINVAL, Iam, "Remove");
169  return;
170 }
171
172
173
174
175 // Move a file/directory to another path
176
177 void  OSD_FileNode::Move(const OSD_Path& NewPath){
178 int status;
179 TCollection_AsciiString thisPath;
180
181 // if (myPath.Name().Length()==0)
182 //  OSD_OSDError::Raise("OSD_FileNode::Move : no name was given");
183
184 // if (Failed()) Perror();
185
186  NewPath.SystemName( thisPath );        // Get internal path name
187  TCollection_AsciiString aBuffer;
188  myPath.SystemName ( aBuffer );
189  status = rename (aBuffer.ToCString(), thisPath.ToCString());
190
191  if (status == -1) myError.SetValue (errno, Iam, "Move");
192 }
193
194
195
196
197
198 // Copy a file to another path and name
199
200
201 #ifndef WNT
202
203 int static copy_file( const char* src, const char* trg )
204 {
205   int err=0;
206   errno=0;
207   int fds = open( src, O_RDONLY );
208   if ( fds <0 )
209     return errno;
210
211   int fdo = open( trg, O_WRONLY|O_TRUNC| O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
212   if ( fdo <0 )
213   {
214     err = errno;
215     close( fds );
216     return err;
217   }
218
219   const int BUFSIZE=4096;
220   char buf[BUFSIZE];
221   int n=0;
222   while ( ( n = read ( fds, buf, BUFSIZE )) >0 )
223   {
224     if ( write ( fdo, buf, n ) != n ) { // writing error
225       if ( ! errno )
226         errno = ENOSPC;
227       break;
228     }
229   }
230
231   err=errno;
232   close( fdo );
233   if (!err) err=errno;
234   close( fds );
235   if (!err) err=errno;
236   return err;
237 }
238
239 #endif
240
241
242
243
244 void  OSD_FileNode::Copy(const OSD_Path& ToPath)
245 {
246 int status;
247 TCollection_AsciiString second_name;
248
249 // if (myPath.Name().Length()==0)   Copy .login would raise !!
250 //  OSD_OSDError::Raise("OSD_FileNode::Copy : no name was given");
251 // if (Failed()) Perror();
252
253  ToPath.SystemName (second_name);
254
255  TCollection_AsciiString aBuffer;
256  myPath.SystemName ( aBuffer );
257  status =  copy_file(aBuffer.ToCString(), second_name.ToCString());
258  if (status != 0) myError.SetValue (-1, Iam, "Copy failed") ;// (LD)
259 #ifdef DEBUG
260  printf("Status %d : errno # %d\n",status,errno);
261 #endif
262 }
263
264
265
266
267
268 // Get protections of a file/directory
269
270 OSD_Protection  OSD_FileNode::Protection(){
271 OSD_Protection thisProt;
272 struct stat myStat;
273 int status;
274 int s,u,g,w;
275
276 // if (myPath.Name().Length()==0)
277 //  OSD_OSDError::Raise("OSD_FileNode::Protection : no name was given");
278
279 // if (Failed()) Perror();
280
281  TCollection_AsciiString aBuffer;
282  myPath.SystemName ( aBuffer );
283  status = stat(aBuffer.ToCString(), &myStat);
284  if (status == -1) myError.SetValue (errno, Iam, "Protection");
285
286  u = g = w = OSD_None;
287
288  if (myStat.st_mode & S_IRUSR)  u |= OSD_R;
289  if (myStat.st_mode & S_IWUSR)  u |= OSD_W;
290  if (myStat.st_mode & S_IXUSR)  u |= OSD_X;
291
292  if (myStat.st_mode & S_IRGRP)  g |= OSD_R;
293  if (myStat.st_mode & S_IWGRP)  g |= OSD_W;
294  if (myStat.st_mode & S_IXGRP)  g |= OSD_X;
295
296  if (myStat.st_mode & S_IROTH)  w |= OSD_R;
297  if (myStat.st_mode & S_IWOTH)  w |= OSD_W;
298  if (myStat.st_mode & S_IXOTH)  w |= OSD_X;
299
300  s = g;
301  thisProt.SetValues ((OSD_SingleProtection)s,
302                      (OSD_SingleProtection)u,
303                      (OSD_SingleProtection)g,
304                      (OSD_SingleProtection)w);
305
306  return (thisProt);
307 }
308
309
310 // Set protections of a file/directory
311
312 void  OSD_FileNode::SetProtection(const OSD_Protection& Prot){
313 int status;
314
315 //  if (myPath.Name().Length()==0)
316 //  OSD_OSDError::Raise("OSD_FileNode::SetProtection : no name was given");
317
318 // if (Failed()) Perror();
319
320  TCollection_AsciiString aBuffer;
321  myPath.SystemName ( aBuffer );
322  status = chmod (aBuffer.ToCString(), (mode_t)Prot.Internal() );
323  if (status == -1) myError.SetValue (errno, Iam, "SetProtection");
324 }
325
326
327
328 // Returns User Id
329
330 Standard_Integer OSD_FileNode::UserId(){
331 struct stat buffer;
332
333 // if (myPath.Name().Length()==0)
334 //  OSD_OSDError::Raise("OSD_FileNode::UserId : no name was given");
335
336 // if (Failed()) Perror();
337
338  /* Get File Informations */
339
340  TCollection_AsciiString aBuffer;
341  myPath.SystemName ( aBuffer );
342  stat ( aBuffer.ToCString(), &buffer );
343
344  return ( buffer.st_uid );
345 }
346
347
348 // Returns Group Id
349
350 Standard_Integer OSD_FileNode::GroupId(){
351 struct stat buffer;
352
353 // if (myPath.Name().Length()==0)
354 //  OSD_OSDError::Raise("OSD_FileNode::GroupId : no name was given");
355
356 // if (Failed()) Perror();
357
358  /* Get File Informations */
359
360  TCollection_AsciiString aBuffer;
361  myPath.SystemName ( aBuffer );
362  stat ( aBuffer.ToCString(), &buffer );
363
364  return ( buffer.st_gid );
365 }
366
367
368
369
370 // return the date of last access of file/directory
371
372 Quantity_Date  OSD_FileNode::CreationMoment(){
373
374  Quantity_Date result;
375  struct tm *decode;
376  struct stat buffer;
377
378 // if (myPath.Name().Length()==0)
379 //  OSD_OSDError::Raise("OSD_FileNode::CreationMoment : no name was given");
380
381 // if (Failed()) Perror();
382
383  /* Get File Informations */
384
385  TCollection_AsciiString aBuffer;
386  myPath.SystemName ( aBuffer );
387  if (!stat ( aBuffer.ToCString(), &buffer )) {
388    decode = localtime(&buffer.st_ctime);
389    result.SetValues ( 
390                      decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
391                      decode->tm_hour, decode->tm_min, decode->tm_sec , 0,0);
392  }
393  else
394    result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
395  return (result);
396 }
397
398 // return Last access of file/directory
399
400 Quantity_Date  OSD_FileNode::AccessMoment(){
401
402  Quantity_Date result;
403  struct tm *decode;
404  struct stat buffer;
405
406 // if (myPath.Name().Length()==0)
407 //  OSD_OSDError::Raise("OSD_FileNode::AccessMoment : no name was given");
408
409 // if (Failed()) Perror();
410
411  /* Get File Informations */
412
413  TCollection_AsciiString aBuffer;
414  myPath.SystemName ( aBuffer );
415  if (!stat ( aBuffer.ToCString(), &buffer )) {
416    decode = localtime(&buffer.st_atime);
417    result.SetValues (
418                      decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
419                      decode->tm_hour, decode->tm_min, decode->tm_sec, 0,0 );
420  }
421  else
422    result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
423  return (result);
424 }
425
426
427 void OSD_FileNode::Reset(){
428  myError.Reset();
429 }
430
431 Standard_Boolean OSD_FileNode::Failed()const{
432  return( myError.Failed());
433 }
434
435 void OSD_FileNode::Perror() {
436  myError.Perror();
437 }
438
439
440 Standard_Integer OSD_FileNode::Error()const{
441  return( myError.Error());
442 }
443
444 #else
445
446 //----------------------------------------------------------------------------
447 //-------------------  WNT Sources of OSD_FileNode ---------------------------
448 //----------------------------------------------------------------------------
449
450 #define STRICT
451 #include <OSD_FileNode.hxx>
452 #include <OSD_Protection.hxx>
453 #include <Quantity_Date.hxx>
454 #include <Standard_ProgramError.hxx>
455
456 #include <OSD_WNT_1.hxx>
457
458 #ifndef _INC_TCHAR
459 # include <tchar.h>
460 #endif  // _INC_TCHAR
461
462 #define TEST_RAISE( arg ) _test_raise (  fName, ( arg )  )
463 #define RAISE( arg ) Standard_ProgramError :: Raise (  ( arg )  )
464
465 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, char* = NULL );
466 BOOL                 __fastcall _osd_wnt_sd_to_protection (
467                                  PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL
468                                 );
469 Standard_Integer     __fastcall _get_file_type ( Standard_CString, Standard_Integer );
470
471 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
472
473 static BOOL __fastcall _get_file_time ( Standard_CString, LPSYSTEMTIME, BOOL );
474 static void __fastcall _test_raise ( TCollection_AsciiString, Standard_CString );
475
476 //=======================================================================
477 //function : OSD_FileNode
478 //purpose  : Empty Constructor
479 //=======================================================================
480
481 OSD_FileNode::OSD_FileNode () {
482
483  myFileChannel = ( Standard_Integer )INVALID_HANDLE_VALUE;
484
485 }  // end constructor ( 1 )
486
487 //=======================================================================
488 //function : OSD_FileNode
489 //purpose  : Constructor
490 //=======================================================================
491
492 OSD_FileNode::OSD_FileNode ( const OSD_Path& Name ) {
493
494  myFileChannel = ( Standard_Integer )INVALID_HANDLE_VALUE;
495  myPath        = Name;
496
497 }  // end constructor ( 2 )
498
499 //=======================================================================
500 //function : Path
501 //purpose  : 
502 //=======================================================================
503
504 void OSD_FileNode::Path ( OSD_Path& Name ) const {
505
506  Name = myPath;
507
508 }  // end OSD_FileNode :: Path
509
510 //=======================================================================
511 //function : SetPath
512 //purpose  : 
513 //=======================================================================
514
515 void OSD_FileNode::SetPath ( const OSD_Path& Name ) {
516
517  myPath = Name;
518
519 }  // end OSD_FileNode :: SetPath
520
521 //=======================================================================
522 //function : Exists
523 //purpose  : 
524 //=======================================================================
525
526 Standard_Boolean OSD_FileNode::Exists () {
527
528  Standard_Boolean        retVal = Standard_False;;
529  TCollection_AsciiString fName;
530
531  myPath.SystemName ( fName );
532
533  if (  fName.IsEmpty ()  ) return Standard_False;
534  TEST_RAISE(  TEXT( "Exists" )  );
535
536  if (  GetFileAttributes (  fName.ToCString ()  ) == 0xFFFFFFFF  ) {
537  
538   if (  GetLastError () != ERROR_FILE_NOT_FOUND  )
539
540    _osd_wnt_set_error (  myError, OSD_WFileNode, fName.ToCString ()  );
541  
542  } else
543
544   retVal = Standard_True;
545
546  return retVal;
547
548 }  // end OSD_FileNode :: Exists
549
550 //=======================================================================
551 //function : Remove
552 //purpose  : 
553 //=======================================================================
554
555 void OSD_FileNode::Remove () {
556
557  TCollection_AsciiString fName;
558
559  myPath.SystemName ( fName );
560
561  TEST_RAISE(  TEXT( "Remove" )  );
562
563  switch (  _get_file_type (  fName.ToCString (),
564                              ( Standard_Integer )INVALID_HANDLE_VALUE )  ) {
565
566   case FLAG_FILE:
567
568    if (   !DeleteFile (  fName.ToCString ()  )   )
569
570     _osd_wnt_set_error (  myError, OSD_WFileNode,  fName.ToCString ()  );
571
572   break;
573
574   case FLAG_DIRECTORY:
575
576
577 // LD : Suppression de l'appel a DeleteDirectory pour 
578 //      ne pas detruire un repertoire no vide.
579
580    if (   !RemoveDirectory (  fName.ToCString ()  )   )
581
582     _osd_wnt_set_error (  myError, OSD_WFileNode, fName.ToCString ()  );
583
584   break;
585
586   default:
587
588    RAISE(  TEXT( "OSD_FileNode :: Remove ():"
589                  " invalid file type - neither file nor directory" )  );
590
591  }  // end switch
592
593 }  // end OSD_FileNode :: Remove
594
595 //=======================================================================
596 //function : Move
597 //purpose  : 
598 //=======================================================================
599
600 void OSD_FileNode::Move ( const OSD_Path& NewPath ) {
601
602  TCollection_AsciiString fName;
603  TCollection_AsciiString fNameDst;
604
605  myPath.SystemName  ( fName );
606
607  TEST_RAISE(  TEXT( "Move" )  );
608
609  NewPath.SystemName ( fNameDst );
610
611  switch (  _get_file_type ( fName.ToCString (),
612                             ( Standard_Integer )INVALID_HANDLE_VALUE )  ) {
613
614   case FLAG_FILE:
615
616    if (!MoveFileEx (fName.ToCString (), fNameDst.ToCString (),
617                     MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
618                     )
619        )
620  
621      _osd_wnt_set_error ( myError, OSD_WFileNode,
622                           fName.ToCString (), fNameDst.ToCString ()  );
623   break;
624
625   case FLAG_DIRECTORY:
626
627    if (   !MoveDirectory (
628             fName.ToCString (), fNameDst.ToCString ()
629            )
630    )
631  
632     _osd_wnt_set_error ( myError, OSD_WFileNode,
633                          fName.ToCString (), fNameDst.ToCString ()  );
634
635   break;
636
637   default:
638
639    RAISE(  TEXT( "OSD_FileNode :: Move (): "
640                  "invalid file type - neither file nor directory" )  );
641
642  }  // end switch
643
644 }  // end OSD_FileNode :: Move
645
646 //=======================================================================
647 //function : Copy
648 //purpose  : 
649 //=======================================================================
650
651 void OSD_FileNode::Copy ( const OSD_Path& ToPath ) {
652
653  TCollection_AsciiString fName;
654  TCollection_AsciiString fNameDst;
655
656  myPath.SystemName ( fName );
657
658  TEST_RAISE(  TEXT( "Copy" )  );
659
660  ToPath.SystemName ( fNameDst );
661
662  switch (  _get_file_type ( fName.ToCString (),
663                             ( Standard_Integer )INVALID_HANDLE_VALUE )  ) {
664
665   case FLAG_FILE:
666
667    if (!CopyFile (fName.ToCString (), fNameDst.ToCString (), FALSE ))
668      _osd_wnt_set_error (myError, OSD_WFileNode,
669                          fName.ToCString (), fNameDst.ToCString ());
670   break;
671
672   case FLAG_DIRECTORY:
673
674    if (   !CopyDirectory (
675             fName.ToCString (), fNameDst.ToCString ()
676           )
677    )
678  
679     _osd_wnt_set_error (
680      myError, OSD_WFileNode, fName.ToCString (), fNameDst.ToCString ()
681     );
682
683   break;
684
685   default:
686
687    RAISE(  TEXT( "OSD_FileNode :: Copy ():"
688                  " invalid file type - neither file nor directory" )  );
689
690  }  // end switch
691
692 }  // end OSD_FileNode :: Copy
693
694 //=======================================================================
695 //function : Protection
696 //purpose  : 
697 //=======================================================================
698
699 OSD_Protection OSD_FileNode::Protection () {
700
701  OSD_Protection          retVal;
702  TCollection_AsciiString fName;
703  PSECURITY_DESCRIPTOR    pSD;
704
705  myPath.SystemName ( fName );
706
707  TEST_RAISE(  TEXT( "Protection" )  );
708
709  if (   (  pSD = GetFileSecurityEx (
710                   fName.ToCString (), DACL_SECURITY_INFORMATION |
711                   OWNER_SECURITY_INFORMATION
712                  )
713         ) == NULL ||
714         !_osd_wnt_sd_to_protection (
715           pSD, retVal,
716           _get_file_type (  fName.ToCString (), ( Standard_Integer )INVALID_HANDLE_VALUE  ) ==
717           FLAG_DIRECTORY
718          )
719  )
720    
721    _osd_wnt_set_error ( myError, OSD_WFileNode );
722
723  if ( pSD != NULL )
724
725   FreeFileSecurity ( pSD );
726
727  return retVal;
728
729 }  // end OSD_FileNode :: Protection
730
731 //=======================================================================
732 //function : SetProtection
733 //purpose  : 
734 //=======================================================================
735
736 void OSD_FileNode::SetProtection ( const OSD_Protection& Prot ) {
737
738  TCollection_AsciiString fName;
739  PSECURITY_DESCRIPTOR    pSD;
740
741  myPath.SystemName ( fName );
742
743  TEST_RAISE(  TEXT( "SetProtection" )  );
744
745  pSD = _osd_wnt_protection_to_sd (
746         Prot,
747         _get_file_type ( fName.ToCString (),
748                          ( Standard_Integer )INVALID_HANDLE_VALUE  ) ==
749         FLAG_DIRECTORY,
750         (char *)fName.ToCString ()
751        );
752  
753  if ( pSD == NULL || !SetFileSecurity (
754                        fName.ToCString (), DACL_SECURITY_INFORMATION, pSD
755                       )
756  )
757   
758   _osd_wnt_set_error (  myError, OSD_WFileNode, fName.ToCString ()  );
759
760  if ( pSD != NULL )
761
762   FreeSD ( pSD );
763
764 }  // end OSD_FileNode :: SetProtection
765
766 //=======================================================================
767 //function : AccessMoment
768 //purpose  : 
769 //=======================================================================
770
771 Quantity_Date OSD_FileNode::AccessMoment () {
772
773  Quantity_Date           retVal;
774  SYSTEMTIME              stAccessMoment;
775  SYSTEMTIME              stAccessSystemMoment;
776  TCollection_AsciiString fName;
777
778  myPath.SystemName ( fName );
779
780  TEST_RAISE(  TEXT( "AccessMoment" )  );
781
782 // if (   _get_file_time (  fName.ToCString (), &stAccessMoment, TRUE  )   )
783  if (   _get_file_time (  fName.ToCString (), &stAccessSystemMoment, TRUE  ) )
784 //POP
785 {
786   SYSTEMTIME * aSysTime = &stAccessMoment;
787   BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL ,
788                                                 &stAccessSystemMoment ,
789                                                 &stAccessMoment);
790   if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
791     aSysTime = &stAccessSystemMoment;
792   retVal.SetValues (aSysTime->wMonth,       aSysTime->wDay,
793                     aSysTime->wYear,        aSysTime->wHour,
794                     aSysTime->wMinute,      aSysTime->wSecond,
795                     aSysTime->wMilliseconds
796                     );
797 }
798  else
799
800   _osd_wnt_set_error (  myError, OSD_WFileNode, fName.ToCString ()  );
801
802  return retVal;
803
804 }  // end OSD_FileNode :: AccessMoment
805
806 //=======================================================================
807 //function : CreationMoment
808 //purpose  : 
809 //=======================================================================
810
811 Quantity_Date OSD_FileNode::CreationMoment () {
812
813  Quantity_Date           retVal;
814  SYSTEMTIME              stCreationMoment;
815  SYSTEMTIME              stCreationSystemMoment;
816  TCollection_AsciiString fName;
817
818  myPath.SystemName ( fName );
819
820  TEST_RAISE(  TEXT( "CreationMoment" )  );
821
822 // if (   _get_file_time (  fName.ToCString (), &stCreationMoment, FALSE  )   )
823  if ( _get_file_time ( fName.ToCString (), &stCreationSystemMoment, TRUE  )   ) 
824 //POP 
825 {
826   SYSTEMTIME * aSysTime = &stCreationMoment;
827   BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL,
828                                                 &stCreationSystemMoment ,
829                                                 &stCreationMoment);
830   if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
831     aSysTime = &stCreationSystemMoment;
832   retVal.SetValues (aSysTime->wMonth,       aSysTime->wDay,
833                     aSysTime->wYear,        aSysTime->wHour,
834                     aSysTime->wMinute,      aSysTime->wSecond,
835                     aSysTime->wMilliseconds
836                     );
837 }
838  else
839
840   _osd_wnt_set_error (  myError, OSD_WFileNode, fName.ToCString ()  );
841
842  return retVal;
843
844 }  // end OSD_FileNode :: CreationMoment
845
846 //=======================================================================
847 //function : UserId
848 //purpose  : 
849 //=======================================================================
850
851 Standard_Integer OSD_FileNode::UserId () {
852
853  PSID                    pSIDowner = NULL;
854  PSID                    retVal = NULL;
855  BOOL                    fDefaulted;
856  TCollection_AsciiString fName;
857  PSECURITY_DESCRIPTOR    pSD;
858
859  myPath.SystemName ( fName );
860
861  TEST_RAISE(  TEXT( "UserId" )  );
862
863  if (   (  pSD = GetFileSecurityEx (
864                   fName.ToCString (),
865                   OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
866                  )
867         ) != NULL                                                   &&
868         GetSecurityDescriptorOwner ( pSD, &pSIDowner, &fDefaulted ) &&
869         pSIDowner != NULL
870  )
871  
872   retVal = CopySidEx ( pSIDowner );
873
874  else
875
876   _osd_wnt_set_error ( myError, OSD_WFileNode );
877
878  if ( pSD != NULL )
879
880   FreeFileSecurity ( pSD );
881  
882  return ( Standard_Integer )retVal;
883
884 }  // end OSD_FileNode :: UserId
885
886 //=======================================================================
887 //function : GroupId
888 //purpose  : 
889 //=======================================================================
890
891 Standard_Integer OSD_FileNode::GroupId () {
892
893  PGROUP_SID              retVal = NULL;
894  TCollection_AsciiString fName;
895  PSECURITY_DESCRIPTOR    pSD;
896
897  myPath.SystemName ( fName );
898
899  TEST_RAISE(  TEXT( "GroupId" )  );
900
901  if (   (  pSD = GetFileSecurityEx (
902                   fName.ToCString (),
903                   OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
904                  )
905         ) != NULL
906  ) {
907
908   retVal = AllocGroupSid ( pSD );
909   FreeFileSecurity ( pSD );
910
911  } else
912
913   _osd_wnt_set_error ( myError, OSD_WFileNode );
914
915  return ( Standard_Integer )retVal;
916
917 }  // end OSD_FileNode :: GroupId
918
919 //=======================================================================
920 //function : Failed
921 //purpose  : 
922 //=======================================================================
923
924 Standard_Boolean OSD_FileNode::Failed () const {
925
926  return myError.Failed ();
927
928 }  // end OSD_FileNode :: Failed
929
930 //=======================================================================
931 //function : Reset
932 //purpose  : 
933 //=======================================================================
934
935 void OSD_FileNode::Reset () {
936
937  myError.Reset ();
938
939 }  // end OSD_FileNode :: Reset
940
941 //=======================================================================
942 //function : Perror
943 //purpose  : 
944 //=======================================================================
945
946 void OSD_FileNode::Perror () {
947
948  myError.Perror ();
949
950 }  // end OSD_FileNode :: Perror
951
952 //=======================================================================
953 //function : Error
954 //purpose  : 
955 //=======================================================================
956
957 Standard_Integer OSD_FileNode::Error () const {
958
959  return myError.Error ();
960
961 }  // end OSD_FileNode :: Error
962
963 void _osd_wnt_set_error ( OSD_Error& err, OSD_WhoAmI who, ... ) {
964
965  DWORD              errCode;
966  Standard_Character buffer[ 2048 ];
967  va_list            arg_ptr;
968
969  va_start ( arg_ptr, err );
970
971  errCode = GetLastError ();
972
973  if (  !FormatMessage (
974          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
975          0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
976          buffer, 2048, &arg_ptr
977         )
978  ) {
979  
980   sprintf ( buffer, "error code %d", (Standard_Integer)errCode );
981   SetLastError ( errCode );
982
983  }  // end if
984
985  err.SetValue ( errCode, who, buffer );
986
987  va_end ( arg_ptr );
988
989 }  // end _set_error
990
991 #if defined(__CYGWIN32__) || defined(__MINGW32__)
992 #define __try
993 #define __finally
994 #define __leave return retVal
995 #endif
996
997 static BOOL __fastcall _get_file_time (
998                         Standard_CString fName, LPSYSTEMTIME lpSysTime, BOOL fAccess
999                        ) {
1000
1001  BOOL       retVal = FALSE;
1002  FILETIME   ftCreationTime;
1003  FILETIME   ftLastWriteTime;
1004  LPFILETIME lpftPtr;
1005  HANDLE     hFile = INVALID_HANDLE_VALUE;
1006
1007  __try {
1008
1009   if (   (  hFile = CreateFile (
1010                      fName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
1011                     )
1012          ) == INVALID_HANDLE_VALUE
1013   ) __leave;
1014
1015   if (  !GetFileTime ( hFile, &ftCreationTime, NULL, &ftLastWriteTime )  ) __leave;
1016
1017   lpftPtr = fAccess ? &ftLastWriteTime : &ftCreationTime;
1018
1019   if (  !FileTimeToSystemTime ( lpftPtr, lpSysTime )  ) __leave;
1020
1021   retVal = TRUE;
1022
1023  }  // end __try
1024
1025  __finally {
1026  
1027   if ( hFile != INVALID_HANDLE_VALUE )
1028
1029    CloseHandle ( hFile );
1030  
1031  }  // end __finally
1032
1033 #ifdef VAC
1034 leave: ;      // added for VisualAge
1035 #endif
1036
1037  return retVal;
1038
1039 }  // end _get_file_time
1040
1041 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1042 #undef __try
1043 #undef __finally
1044 #undef __leave
1045 #endif
1046
1047 static void __fastcall _test_raise ( TCollection_AsciiString fName, Standard_CString str ) {
1048
1049  Standard_Character buff[ 64 ];
1050
1051  if (  fName.IsEmpty ()  ) {
1052  
1053   _tcscpy (  buff, TEXT( "OSD_FileNode :: " )  );
1054   _tcscat (  buff, str );
1055   _tcscat (  buff, TEXT( " (): wrong access" )  );
1056
1057   Standard_ProgramError :: Raise ( buff );
1058  
1059  }  // end if
1060
1061 }  // end _test_raise
1062
1063 #endif