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