0027350: Support for Universal Windows Platform
[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 <OSD_FileNode.hxx>
22 #include <OSD_OSDError.hxx>
23 #include <OSD_Path.hxx>
24 #include <OSD_Protection.hxx>
25 #include <OSD_WhoAmI.hxx>
26 #include <Quantity_Date.hxx>
27 #include <Standard_NullObject.hxx>
28 #include <Standard_ProgramError.hxx>
29
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 // For "system"
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 // return the date of last access of file/directory
286
287 Quantity_Date  OSD_FileNode::CreationMoment(){
288
289  Quantity_Date result;
290  struct tm *decode;
291  struct stat buffer;
292
293 // if (myPath.Name().Length()==0)
294 //  OSD_OSDError::Raise("OSD_FileNode::CreationMoment : no name was given");
295
296 // if (Failed()) Perror();
297
298  /* Get File Informations */
299
300  TCollection_AsciiString aBuffer;
301  myPath.SystemName ( aBuffer );
302  if (!stat ( aBuffer.ToCString(), &buffer )) {
303    time_t aTime = (time_t)buffer.st_ctime;
304    decode = localtime (&aTime);
305    result.SetValues (decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
306                      decode->tm_hour, decode->tm_min, decode->tm_sec , 0,0);
307  }
308  else
309    result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
310  return (result);
311 }
312
313 // return Last access of file/directory
314
315 Quantity_Date  OSD_FileNode::AccessMoment(){
316
317  Quantity_Date result;
318  struct tm *decode;
319  struct stat buffer;
320
321 // if (myPath.Name().Length()==0)
322 //  OSD_OSDError::Raise("OSD_FileNode::AccessMoment : no name was given");
323
324 // if (Failed()) Perror();
325
326  /* Get File Informations */
327
328  TCollection_AsciiString aBuffer;
329  myPath.SystemName ( aBuffer );
330  if (!stat ( aBuffer.ToCString(), &buffer )) {
331    time_t aTime = (time_t)buffer.st_ctime;
332    decode = localtime (&aTime);
333    result.SetValues (decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
334                      decode->tm_hour, decode->tm_min, decode->tm_sec, 0,0 );
335  }
336  else
337    result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
338  return (result);
339 }
340
341
342 void OSD_FileNode::Reset(){
343  myError.Reset();
344 }
345
346 Standard_Boolean OSD_FileNode::Failed()const{
347  return( myError.Failed());
348 }
349
350 void OSD_FileNode::Perror() {
351  myError.Perror();
352 }
353
354
355 Standard_Integer OSD_FileNode::Error()const{
356  return( myError.Error());
357 }
358
359 #else /* _WIN32 */
360
361 //----------------------------------------------------------------------------
362 //-------------------  WNT Sources of OSD_FileNode ---------------------------
363 //----------------------------------------------------------------------------
364
365 #define STRICT
366 #ifdef NONLS
367 #undef NONLS
368 #endif
369 #include <windows.h>
370
371 #include <OSD_FileNode.hxx>
372 #include <OSD_Protection.hxx>
373 #include <Quantity_Date.hxx>
374 #include <Standard_ProgramError.hxx>
375 #include <TCollection_ExtendedString.hxx>
376
377 #include <OSD_WNT_1.hxx>
378
379 #ifndef _INC_TCHAR
380 # include <tchar.h>
381 #endif  // _INC_TCHAR
382
383 #include <Strsafe.h>
384
385 #define TEST_RAISE( arg ) _test_raise (  fName, ( arg )  )
386 #define RAISE( arg ) Standard_ProgramError :: Raise (  ( arg )  )
387
388 #ifndef OCCT_UWP
389 // None of the existing security APIs are supported in a UWP applications
390 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, wchar_t* = NULL );
391 BOOL                 __fastcall _osd_wnt_sd_to_protection (
392                                  PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL
393                                 );
394 #endif
395 Standard_Integer     __fastcall _get_file_type ( Standard_CString, HANDLE );
396
397 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
398
399 static BOOL __fastcall _get_file_time ( Standard_ExtString, LPSYSTEMTIME, BOOL );
400 static void __fastcall _test_raise ( TCollection_AsciiString, Standard_CString );
401
402 //=======================================================================
403 //function : OSD_FileNode
404 //purpose  : Empty Constructor
405 //=======================================================================
406
407 OSD_FileNode::OSD_FileNode () 
408 {
409 }
410
411 //=======================================================================
412 //function : OSD_FileNode
413 //purpose  : Constructor
414 //=======================================================================
415
416 OSD_FileNode::OSD_FileNode ( const OSD_Path& Name )
417 {
418  myPath        = Name;
419 }  // end constructor ( 2 )
420
421 //=======================================================================
422 //function : Path
423 //purpose  : 
424 //=======================================================================
425
426 void OSD_FileNode::Path ( OSD_Path& Name ) const {
427
428  Name = myPath;
429
430 }  // end OSD_FileNode :: Path
431
432 //=======================================================================
433 //function : SetPath
434 //purpose  : 
435 //=======================================================================
436
437 void OSD_FileNode::SetPath ( const OSD_Path& Name ) {
438
439  myPath = Name;
440
441 }  // end OSD_FileNode :: SetPath
442
443 //=======================================================================
444 //function : Exists
445 //purpose  : 
446 //=======================================================================
447
448 Standard_Boolean OSD_FileNode::Exists () {
449
450  Standard_Boolean        retVal = Standard_False;;
451  TCollection_AsciiString fName;
452
453  myPath.SystemName ( fName );
454
455  if (  fName.IsEmpty ()  ) return Standard_False;
456  TEST_RAISE(  "Exists"  );
457
458  // make wide character string from UTF-8
459  TCollection_ExtendedString fNameW(fName);
460
461  WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
462
463  if ( !GetFileAttributesExW((const wchar_t*)fNameW.ToExtString(), GetFileExInfoStandard, &aFileInfo)) {
464
465   if (  GetLastError () != ERROR_FILE_NOT_FOUND  )
466     _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
467
468  } else
469
470   retVal = Standard_True;
471
472  return retVal;
473
474 }  // end OSD_FileNode :: Exists
475
476 //=======================================================================
477 //function : Remove
478 //purpose  : 
479 //=======================================================================
480
481 void OSD_FileNode::Remove () {
482
483  TCollection_AsciiString fName;
484
485  myPath.SystemName ( fName );
486  TCollection_ExtendedString fNameW(fName);
487
488  TEST_RAISE(  "Remove"  );
489
490  switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
491
492   case FLAG_FILE:
493
494    if (   !DeleteFileW (  (const wchar_t*) fNameW.ToExtString ()  )   )
495      _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
496   break;
497
498   case FLAG_DIRECTORY:
499
500
501 // LD : Suppression de l'appel a DeleteDirectory pour 
502 //      ne pas detruire un repertoire no vide.
503
504    if (   !RemoveDirectoryW ( (const wchar_t*) fNameW.ToExtString ()  )   )
505      _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
506   break;
507
508   default:
509    RAISE("OSD_FileNode :: Remove (): invalid file type - neither file nor directory");
510  }  // end switch
511
512 }  // end OSD_FileNode :: Remove
513
514 //=======================================================================
515 //function : Move
516 //purpose  : 
517 //=======================================================================
518
519 void OSD_FileNode::Move ( const OSD_Path& NewPath ) {
520
521  TCollection_AsciiString fName;
522  TCollection_AsciiString fNameDst;
523
524  myPath.SystemName  ( fName );
525  TCollection_ExtendedString fNameW(fName);
526
527  TEST_RAISE(  "Move"  );
528
529  NewPath.SystemName ( fNameDst );
530  TCollection_ExtendedString fNameDstW(fNameDst);
531
532  switch (_get_file_type (fName.ToCString (), INVALID_HANDLE_VALUE)) {
533
534   case FLAG_FILE:
535
536    if (!MoveFileExW ((const wchar_t*)fNameW.ToExtString (),
537                      (const wchar_t*)fNameDstW.ToExtString (),
538                      MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
539                      )
540        )
541      _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
542   break;
543
544   case FLAG_DIRECTORY:
545
546    if (   !MoveDirectory (
547             (const wchar_t*) fNameW.ToExtString (), (const wchar_t*) fNameDstW.ToExtString ()
548            )
549    )
550    _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
551   break;
552
553   default:
554    RAISE("OSD_FileNode :: Move (): invalid file type - neither file nor directory");
555  }  // end switch
556
557 }  // end OSD_FileNode :: Move
558
559 //=======================================================================
560 //function : Copy
561 //purpose  : 
562 //=======================================================================
563
564 void OSD_FileNode::Copy ( const OSD_Path& ToPath ) {
565
566  TCollection_AsciiString fName;
567  TCollection_AsciiString fNameDst;
568
569  myPath.SystemName ( fName );
570  TCollection_ExtendedString fNameW(fName);
571
572  TEST_RAISE(  "Copy"  );
573
574  ToPath.SystemName ( fNameDst );
575  TCollection_ExtendedString fNameDstW(fNameDst);
576
577  switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
578
579   case FLAG_FILE:
580 #ifndef OCCT_UWP
581     if (!CopyFileW((const wchar_t*)fNameW.ToExtString(),
582       (const wchar_t*)fNameDstW.ToExtString(), FALSE))
583 #else
584    if (CopyFile2((const wchar_t*)fNameW.ToExtString (),
585                  (const wchar_t*)fNameDstW.ToExtString (), FALSE ) != S_OK)
586 #endif
587    _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
588   break;
589
590   case FLAG_DIRECTORY:
591
592    if (   !CopyDirectory (
593             (const wchar_t*)fNameW.ToExtString (), (const wchar_t*)fNameDstW.ToExtString ()
594           )
595    )
596
597    _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
598
599   break;
600
601   default:
602    RAISE("OSD_FileNode :: Copy (): invalid file type - neither file nor directory");
603
604  }  // end switch
605
606 }  // end OSD_FileNode :: Copy
607
608 // None of the existing security APIs are supported in a UWP applications
609 #ifndef OCCT_UWP
610
611 //=======================================================================
612 //function : Protection
613 //purpose  : 
614 //=======================================================================
615
616 OSD_Protection OSD_FileNode::Protection () {
617
618  OSD_Protection          retVal;
619  TCollection_AsciiString fName;
620  PSECURITY_DESCRIPTOR    pSD;
621
622  myPath.SystemName ( fName );
623  TCollection_ExtendedString fNameW(fName);
624
625  TEST_RAISE(  "Protection"  );
626
627  if (   (  pSD = GetFileSecurityEx (
628                   (const wchar_t*) fNameW.ToExtString (), DACL_SECURITY_INFORMATION |
629                   OWNER_SECURITY_INFORMATION
630                  )
631         ) == NULL ||
632         !_osd_wnt_sd_to_protection (
633           pSD, retVal,
634           _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY)
635  )
636    
637    _osd_wnt_set_error ( myError, OSD_WFileNode );
638
639  if ( pSD != NULL )
640
641   FreeFileSecurity ( pSD );
642
643  return retVal;
644
645 }  // end OSD_FileNode :: Protection
646
647 //=======================================================================
648 //function : SetProtection
649 //purpose  : 
650 //=======================================================================
651
652 void OSD_FileNode::SetProtection ( const OSD_Protection& Prot ) {
653
654  TCollection_AsciiString fName;
655  PSECURITY_DESCRIPTOR    pSD;
656
657  myPath.SystemName ( fName );
658  TCollection_ExtendedString fNameW(fName);
659
660  TEST_RAISE(  "SetProtection"  );
661
662  pSD = _osd_wnt_protection_to_sd (
663         Prot,
664         _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) ==
665         FLAG_DIRECTORY,
666         (wchar_t *)fNameW.ToExtString ()
667        );
668  
669  if ( pSD == NULL || !SetFileSecurityW (
670                        (const wchar_t*) fNameW.ToExtString (), DACL_SECURITY_INFORMATION, pSD
671                       )
672  )
673   _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
674
675  if ( pSD != NULL )
676
677   FreeSD ( pSD );
678
679 }  // end OSD_FileNode :: SetProtection
680
681 #else /* UWP stub */
682
683 #include <io.h>
684
685 //=======================================================================
686 //function : Protection
687 //purpose  : 
688 //=======================================================================
689
690 OSD_Protection OSD_FileNode::Protection ()
691 {
692  TCollection_AsciiString fName;
693
694  myPath.SystemName ( fName );
695  TCollection_ExtendedString fNameW(fName);
696
697  OSD_SingleProtection aProt = OSD_None;
698  if (_waccess_s ((const wchar_t*)fNameW.ToExtString(), 6))
699    aProt = OSD_RW;
700  else if (_waccess_s ((const wchar_t*)fNameW.ToExtString(), 2))
701    aProt = OSD_W;
702  else if (_waccess_s ((const wchar_t*)fNameW.ToExtString(), 4))
703    aProt = OSD_R;
704
705  // assume full access for system and none for everybody
706  OSD_Protection retVal (OSD_RWXD, aProt, aProt, OSD_None);
707  return retVal;
708 }  // end OSD_FileNode :: Protection
709
710 //=======================================================================
711 //function : SetProtection
712 //purpose  : 
713 //=======================================================================
714
715 void OSD_FileNode::SetProtection ( const OSD_Protection& /*Prot*/ )
716 {
717 }  // end OSD_FileNode :: SetProtection
718
719 #endif
720
721 //=======================================================================
722 //function : AccessMoment
723 //purpose  : 
724 //=======================================================================
725
726 Quantity_Date OSD_FileNode::AccessMoment () {
727
728  Quantity_Date           retVal;
729  SYSTEMTIME              stAccessMoment;
730  SYSTEMTIME              stAccessSystemMoment;
731  TCollection_AsciiString fName;
732
733  myPath.SystemName ( fName );
734  TCollection_ExtendedString fNameW(fName);
735
736  TEST_RAISE(  "AccessMoment"  );
737
738 // if (   _get_file_time (  fName.ToCString (), &stAccessMoment, TRUE  )   )
739  if (   _get_file_time (  fNameW.ToExtString (), &stAccessSystemMoment, TRUE  ) )
740 //POP
741 {
742   SYSTEMTIME * aSysTime = &stAccessMoment;
743   BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL ,
744                                                 &stAccessSystemMoment ,
745                                                 &stAccessMoment);
746   if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
747     aSysTime = &stAccessSystemMoment;
748   retVal.SetValues (aSysTime->wMonth,       aSysTime->wDay,
749                     aSysTime->wYear,        aSysTime->wHour,
750                     aSysTime->wMinute,      aSysTime->wSecond,
751                     aSysTime->wMilliseconds
752                     );
753 }
754  else
755   _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
756
757  return retVal;
758
759 }  // end OSD_FileNode :: AccessMoment
760
761 //=======================================================================
762 //function : CreationMoment
763 //purpose  : 
764 //=======================================================================
765
766 Quantity_Date OSD_FileNode::CreationMoment () {
767
768  Quantity_Date           retVal;
769  SYSTEMTIME              stCreationMoment;
770  SYSTEMTIME              stCreationSystemMoment;
771  TCollection_AsciiString fName;
772
773  myPath.SystemName ( fName );
774  TCollection_ExtendedString fNameW(fName);
775
776  TEST_RAISE(  "CreationMoment"  );
777
778 // if (   _get_file_time (  fName.ToCString (), &stCreationMoment, FALSE  )   )
779  if ( _get_file_time ( fNameW.ToExtString (), &stCreationSystemMoment, TRUE  )   ) 
780 //POP 
781 {
782   SYSTEMTIME * aSysTime = &stCreationMoment;
783   BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL,
784                                                 &stCreationSystemMoment ,
785                                                 &stCreationMoment);
786   if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
787     aSysTime = &stCreationSystemMoment;
788   retVal.SetValues (aSysTime->wMonth,       aSysTime->wDay,
789                     aSysTime->wYear,        aSysTime->wHour,
790                     aSysTime->wMinute,      aSysTime->wSecond,
791                     aSysTime->wMilliseconds
792                     );
793 }
794  else
795   _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
796
797  return retVal;
798
799 }  // end OSD_FileNode :: CreationMoment
800
801 //=======================================================================
802 //function : Failed
803 //purpose  : 
804 //=======================================================================
805
806 Standard_Boolean OSD_FileNode::Failed () const {
807
808  return myError.Failed ();
809
810 }  // end OSD_FileNode :: Failed
811
812 //=======================================================================
813 //function : Reset
814 //purpose  : 
815 //=======================================================================
816
817 void OSD_FileNode::Reset () {
818
819  myError.Reset ();
820
821 }  // end OSD_FileNode :: Reset
822
823 //=======================================================================
824 //function : Perror
825 //purpose  : 
826 //=======================================================================
827
828 void OSD_FileNode::Perror () {
829
830  myError.Perror ();
831
832 }  // end OSD_FileNode :: Perror
833
834 //=======================================================================
835 //function : Error
836 //purpose  : 
837 //=======================================================================
838
839 Standard_Integer OSD_FileNode::Error () const {
840
841  return myError.Error ();
842
843 }  // end OSD_FileNode :: Error
844
845 void _osd_wnt_set_error ( OSD_Error& err, OSD_WhoAmI who, ... ) {
846
847  DWORD              errCode;
848
849  wchar_t buffer[2048];
850
851  va_list            arg_ptr;
852
853  va_start ( arg_ptr, who);
854
855  errCode = GetLastError ();
856
857  if (  !FormatMessageW (
858          FORMAT_MESSAGE_FROM_SYSTEM,
859          0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
860          buffer, 2048, &arg_ptr
861         )
862  ) {
863   StringCchPrintfW(buffer, _countof(buffer), L"error code %d", (Standard_Integer)errCode);
864
865   SetLastError ( errCode );
866
867  }  // end if
868
869  char aBufferA[2048];
870  WideCharToMultiByte(CP_UTF8, 0, buffer, -1, aBufferA, sizeof(aBufferA), NULL, NULL);
871  err.SetValue(errCode, who, aBufferA);
872
873  va_end ( arg_ptr );
874
875 }  // end _set_error
876
877 #if defined(__CYGWIN32__) || defined(__MINGW32__)
878 #define __try
879 #define __finally
880 #define __leave return retVal
881 #endif
882
883 static BOOL __fastcall _get_file_time (
884                         Standard_ExtString fName, LPSYSTEMTIME lpSysTime, BOOL fAccess
885                        ) {
886
887  BOOL       retVal = FALSE;
888  FILETIME   ftCreationTime;
889  FILETIME   ftLastWriteTime;
890  LPFILETIME lpftPtr;
891  HANDLE     hFile = INVALID_HANDLE_VALUE;
892
893  __try {
894 #ifndef OCCT_UWP
895    if ((hFile = CreateFileW((const wchar_t*)fName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)
896      ) == INVALID_HANDLE_VALUE
897      )
898 #else
899    CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams = {};
900    pCreateExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
901    pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
902    pCreateExParams.lpSecurityAttributes = NULL;
903    pCreateExParams.hTemplateFile = NULL;
904    if ((hFile = CreateFile2(
905      (const wchar_t*)fName, NULL, NULL,
906      OPEN_EXISTING, &pCreateExParams)
907      ) == INVALID_HANDLE_VALUE
908      )
909 #endif
910     __leave;
911
912   if (  !GetFileTime ( hFile, &ftCreationTime, NULL, &ftLastWriteTime )  ) __leave;
913
914   lpftPtr = fAccess ? &ftLastWriteTime : &ftCreationTime;
915
916   if (  !FileTimeToSystemTime ( lpftPtr, lpSysTime )  ) __leave;
917
918   retVal = TRUE;
919
920  }  // end __try
921
922  __finally {
923  
924   if ( hFile != INVALID_HANDLE_VALUE )
925
926    CloseHandle ( hFile );
927  
928  }  // end __finally
929
930 #ifdef VAC
931 leave: ;      // added for VisualAge
932 #endif
933
934  return retVal;
935
936 }  // end _get_file_time
937
938 #if defined(__CYGWIN32__) || defined(__MINGW32__)
939 #undef __try
940 #undef __finally
941 #undef __leave
942 #endif
943
944 static void __fastcall _test_raise ( TCollection_AsciiString fName, Standard_CString str ) {
945  if (  fName.IsEmpty ()  ) {
946    TCollection_AsciiString buff = "OSD_FileNode :: ";
947    buff += str;
948    buff += " (): wrong access";
949
950    Standard_ProgramError::Raise(buff.ToCString());
951  }  // end if
952
953 }  // end _test_raise
954
955 #endif /* _WIN32 */