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