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