0029917: Foundation Classes - OSD_FileNode AccessMoment and CreationMoment return...
[occt.git] / src / OSD / OSD_FileNode.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
6ff736d8 15#ifndef _WIN32
16
17//----------------------------------------------------------------------------
18//------------------- Linux Sources of OSD_FileNode --------------------------
19//----------------------------------------------------------------------------
7fd59977 20
42cf5bc1 21#include <OSD_FileNode.hxx>
7fd59977 22#include <OSD_OSDError.hxx>
42cf5bc1 23#include <OSD_Path.hxx>
24#include <OSD_Protection.hxx>
7fd59977 25#include <OSD_WhoAmI.hxx>
42cf5bc1 26#include <Quantity_Date.hxx>
27#include <Standard_NullObject.hxx>
28#include <Standard_ProgramError.hxx>
7fd59977 29
7fd59977 30#include <errno.h>
31#include <fcntl.h>
7fd59977 32#include <stdio.h>
42cf5bc1 33#include <stdlib.h>
03155c18 34#include <sys/stat.h>
42cf5bc1 35#include <unistd.h>
36// For "system"
7fd59977 37const OSD_WhoAmI Iam = OSD_WFileNode;
38
39
40// Create a file/directory object
41
6ff736d8 42OSD_FileNode::OSD_FileNode ()
43{
7fd59977 44}
45
7fd59977 46// Create and initialize a file/directory object
47
6ff736d8 48OSD_FileNode::OSD_FileNode (const OSD_Path& Name)
49{
7fd59977 50 SetPath (Name);
51}
52
53
54
55// Get values of object
56
57void OSD_FileNode::Path (OSD_Path& Name)const{
58 Name = myPath;
59}
60
61
62
63
64// Set values of object
65
66void 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
76Standard_Boolean OSD_FileNode::Exists(){
77int status;
78
79
80// if (myPath.Name().Length()==0) A directory can have a null name field (ex: root)
9775fa61 81// throw OSD_OSDError("OSD_FileNode::Exists : no name was given"); (LD)
7fd59977 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
98void OSD_FileNode::Remove(){
99
100// if (myPath.Name().Length()==0) A directory can have a null name field (ex: root)
9775fa61 101// throw OSD_OSDError("OSD_FileNode::Remove : no name was given"); (LD)
7fd59977 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
149void OSD_FileNode::Move(const OSD_Path& NewPath){
150int status;
151TCollection_AsciiString thisPath;
152
153// if (myPath.Name().Length()==0)
9775fa61 154// throw OSD_OSDError("OSD_FileNode::Move : no name was given");
7fd59977 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
7fd59977 166// Copy a file to another path and name
7fd59977 167int 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
7fd59977 203void OSD_FileNode::Copy(const OSD_Path& ToPath)
204{
205int status;
206TCollection_AsciiString second_name;
207
208// if (myPath.Name().Length()==0) Copy .login would raise !!
9775fa61 209// throw OSD_OSDError("OSD_FileNode::Copy : no name was given");
7fd59977 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)
0797d9d3 218#ifdef OCCT_DEBUG
7fd59977 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
229OSD_Protection OSD_FileNode::Protection(){
230OSD_Protection thisProt;
231struct stat myStat;
232int status;
233int s,u,g,w;
234
235// if (myPath.Name().Length()==0)
9775fa61 236// throw OSD_OSDError("OSD_FileNode::Protection : no name was given");
7fd59977 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
271void OSD_FileNode::SetProtection(const OSD_Protection& Prot){
272int status;
273
274// if (myPath.Name().Length()==0)
9775fa61 275// throw OSD_OSDError("OSD_FileNode::SetProtection : no name was given");
7fd59977 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
7fd59977 285// return the date of last access of file/directory
286
287Quantity_Date OSD_FileNode::CreationMoment(){
288
289 Quantity_Date result;
290 struct tm *decode;
291 struct stat buffer;
292
293// if (myPath.Name().Length()==0)
9775fa61 294// throw OSD_OSDError("OSD_FileNode::CreationMoment : no name was given");
7fd59977 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 )) {
0304f711 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,
7fd59977 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
315Quantity_Date OSD_FileNode::AccessMoment(){
316
317 Quantity_Date result;
318 struct tm *decode;
319 struct stat buffer;
320
321// if (myPath.Name().Length()==0)
9775fa61 322// throw OSD_OSDError("OSD_FileNode::AccessMoment : no name was given");
7fd59977 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 )) {
0304f711 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,
7fd59977 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
342void OSD_FileNode::Reset(){
343 myError.Reset();
344}
345
346Standard_Boolean OSD_FileNode::Failed()const{
347 return( myError.Failed());
348}
349
350void OSD_FileNode::Perror() {
351 myError.Perror();
352}
353
354
355Standard_Integer OSD_FileNode::Error()const{
356 return( myError.Error());
357}
358
6ff736d8 359#else /* _WIN32 */
7fd59977 360
361//----------------------------------------------------------------------------
362//------------------- WNT Sources of OSD_FileNode ---------------------------
363//----------------------------------------------------------------------------
364
742cc8b0 365#ifdef NONLS
366#undef NONLS
367#endif
368#include <windows.h>
369
7fd59977 370#include <OSD_FileNode.hxx>
371#include <OSD_Protection.hxx>
372#include <Quantity_Date.hxx>
373#include <Standard_ProgramError.hxx>
d9ff84e8 374#include <TCollection_ExtendedString.hxx>
7fd59977 375
68df8478 376#include <OSD_WNT.hxx>
7fd59977 377
378#ifndef _INC_TCHAR
379# include <tchar.h>
380#endif // _INC_TCHAR
381
5fecc495 382#include <strsafe.h>
742cc8b0 383
7fd59977 384#define TEST_RAISE( arg ) _test_raise ( fName, ( arg ) )
9775fa61 385#define RAISE( arg ) throw Standard_ProgramError ( ( arg ) )
7fd59977 386
742cc8b0 387#ifndef OCCT_UWP
388// None of the existing security APIs are supported in a UWP applications
fb0b0531 389PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, const wchar_t* );
7fd59977 390BOOL __fastcall _osd_wnt_sd_to_protection (
391 PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL
392 );
742cc8b0 393#endif
6ff736d8 394Standard_Integer __fastcall _get_file_type ( Standard_CString, HANDLE );
7fd59977 395
1bd04b5a 396void _osd_wnt_set_error ( OSD_Error&, Standard_Integer, ... );
7fd59977 397
fb0b0531 398static BOOL __fastcall _get_file_time (const wchar_t*, LPSYSTEMTIME, BOOL );
7fd59977 399static void __fastcall _test_raise ( TCollection_AsciiString, Standard_CString );
400
401//=======================================================================
402//function : OSD_FileNode
403//purpose : Empty Constructor
404//=======================================================================
405
6ff736d8 406OSD_FileNode::OSD_FileNode ()
407{
408}
7fd59977 409
410//=======================================================================
411//function : OSD_FileNode
412//purpose : Constructor
413//=======================================================================
414
6ff736d8 415OSD_FileNode::OSD_FileNode ( const OSD_Path& Name )
416{
7fd59977 417 myPath = Name;
7fd59977 418} // end constructor ( 2 )
419
420//=======================================================================
421//function : Path
422//purpose :
423//=======================================================================
424
425void OSD_FileNode::Path ( OSD_Path& Name ) const {
426
427 Name = myPath;
428
429} // end OSD_FileNode :: Path
430
431//=======================================================================
432//function : SetPath
433//purpose :
434//=======================================================================
435
436void OSD_FileNode::SetPath ( const OSD_Path& Name ) {
437
438 myPath = Name;
439
440} // end OSD_FileNode :: SetPath
441
442//=======================================================================
443//function : Exists
444//purpose :
445//=======================================================================
446
73594f72 447Standard_Boolean OSD_FileNode::Exists ()
448{
449 myError.Reset();
7fd59977 450
8c2d3314 451 Standard_Boolean retVal = Standard_False;
7fd59977 452 TCollection_AsciiString fName;
453
454 myPath.SystemName ( fName );
455
456 if ( fName.IsEmpty () ) return Standard_False;
d9ff84e8 457 TEST_RAISE( "Exists" );
7fd59977 458
d9ff84e8 459 // make wide character string from UTF-8
460 TCollection_ExtendedString fNameW(fName);
742cc8b0 461
462 WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
463
fb0b0531 464 if (!GetFileAttributesExW (fNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
465 {
466 if (GetLastError() != ERROR_FILE_NOT_FOUND)
467 {
468 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
469 }
470 }
471 else
472 {
7fd59977 473 retVal = Standard_True;
fb0b0531 474 }
7fd59977 475
476 return retVal;
477
478} // end OSD_FileNode :: Exists
479
480//=======================================================================
481//function : Remove
482//purpose :
483//=======================================================================
484
485void OSD_FileNode::Remove () {
486
487 TCollection_AsciiString fName;
488
489 myPath.SystemName ( fName );
d9ff84e8 490 TCollection_ExtendedString fNameW(fName);
7fd59977 491
d9ff84e8 492 TEST_RAISE( "Remove" );
7fd59977 493
6ff736d8 494 switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
7fd59977 495
496 case FLAG_FILE:
497
fb0b0531 498 if (!DeleteFileW (fNameW.ToWideString()))
499 _osd_wnt_set_error ( myError, OSD_WFileNode, fNameW.ToWideString());
7fd59977 500 break;
501
502 case FLAG_DIRECTORY:
503
504
505// LD : Suppression de l'appel a DeleteDirectory pour
506// ne pas detruire un repertoire no vide.
507
fb0b0531 508 if (!RemoveDirectoryW (fNameW.ToWideString()))
509 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
7fd59977 510 break;
511
512 default:
742cc8b0 513 RAISE("OSD_FileNode :: Remove (): invalid file type - neither file nor directory");
7fd59977 514 } // end switch
515
516} // end OSD_FileNode :: Remove
517
518//=======================================================================
519//function : Move
520//purpose :
521//=======================================================================
522
523void OSD_FileNode::Move ( const OSD_Path& NewPath ) {
524
525 TCollection_AsciiString fName;
526 TCollection_AsciiString fNameDst;
527
528 myPath.SystemName ( fName );
d9ff84e8 529 TCollection_ExtendedString fNameW(fName);
7fd59977 530
d9ff84e8 531 TEST_RAISE( "Move" );
7fd59977 532
533 NewPath.SystemName ( fNameDst );
d9ff84e8 534 TCollection_ExtendedString fNameDstW(fNameDst);
7fd59977 535
6ff736d8 536 switch (_get_file_type (fName.ToCString (), INVALID_HANDLE_VALUE)) {
7fd59977 537
538 case FLAG_FILE:
539
fb0b0531 540 if (!MoveFileExW (fNameW.ToWideString (),
541 fNameDstW.ToWideString (),
542 MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
543 _osd_wnt_set_error(myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
7fd59977 544 break;
545
546 case FLAG_DIRECTORY:
547
fb0b0531 548 if (!MoveDirectory (fNameW.ToWideString(), fNameDstW.ToWideString()))
549 _osd_wnt_set_error(myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
7fd59977 550 break;
551
552 default:
742cc8b0 553 RAISE("OSD_FileNode :: Move (): invalid file type - neither file nor directory");
7fd59977 554 } // end switch
555
556} // end OSD_FileNode :: Move
557
558//=======================================================================
559//function : Copy
560//purpose :
561//=======================================================================
562
563void OSD_FileNode::Copy ( const OSD_Path& ToPath ) {
564
565 TCollection_AsciiString fName;
566 TCollection_AsciiString fNameDst;
567
568 myPath.SystemName ( fName );
d9ff84e8 569 TCollection_ExtendedString fNameW(fName);
7fd59977 570
d9ff84e8 571 TEST_RAISE( "Copy" );
7fd59977 572
573 ToPath.SystemName ( fNameDst );
d9ff84e8 574 TCollection_ExtendedString fNameDstW(fNameDst);
7fd59977 575
6ff736d8 576 switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
7fd59977 577
578 case FLAG_FILE:
742cc8b0 579#ifndef OCCT_UWP
fb0b0531 580 if (!CopyFileW (fNameW.ToWideString(), fNameDstW.ToWideString(), FALSE))
742cc8b0 581#else
fb0b0531 582 if (CopyFile2 (fNameW.ToWideString(), fNameDstW.ToWideString(), FALSE) != S_OK)
742cc8b0 583#endif
fb0b0531 584 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
7fd59977 585 break;
586
587 case FLAG_DIRECTORY:
588
fb0b0531 589 if (!CopyDirectory (fNameW.ToWideString(), fNameDstW.ToWideString()))
590 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
7fd59977 591
592 break;
593
594 default:
742cc8b0 595 RAISE("OSD_FileNode :: Copy (): invalid file type - neither file nor directory");
7fd59977 596
597 } // end switch
598
599} // end OSD_FileNode :: Copy
600
742cc8b0 601// None of the existing security APIs are supported in a UWP applications
602#ifndef OCCT_UWP
603
7fd59977 604//=======================================================================
605//function : Protection
606//purpose :
607//=======================================================================
608
609OSD_Protection OSD_FileNode::Protection () {
610
611 OSD_Protection retVal;
612 TCollection_AsciiString fName;
613 PSECURITY_DESCRIPTOR pSD;
614
615 myPath.SystemName ( fName );
d9ff84e8 616 TCollection_ExtendedString fNameW(fName);
7fd59977 617
d9ff84e8 618 TEST_RAISE( "Protection" );
7fd59977 619
fb0b0531 620 if ((pSD = GetFileSecurityEx (fNameW.ToWideString(), DACL_SECURITY_INFORMATION |OWNER_SECURITY_INFORMATION)) == NULL
621 || !_osd_wnt_sd_to_protection (
7fd59977 622 pSD, retVal,
6ff736d8 623 _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY)
7fd59977 624 )
625
626 _osd_wnt_set_error ( myError, OSD_WFileNode );
627
628 if ( pSD != NULL )
629
630 FreeFileSecurity ( pSD );
631
632 return retVal;
633
634} // end OSD_FileNode :: Protection
635
636//=======================================================================
637//function : SetProtection
638//purpose :
639//=======================================================================
640
641void OSD_FileNode::SetProtection ( const OSD_Protection& Prot ) {
642
643 TCollection_AsciiString fName;
644 PSECURITY_DESCRIPTOR pSD;
645
646 myPath.SystemName ( fName );
d9ff84e8 647 TCollection_ExtendedString fNameW(fName);
7fd59977 648
d9ff84e8 649 TEST_RAISE( "SetProtection" );
7fd59977 650
fb0b0531 651 pSD = _osd_wnt_protection_to_sd (Prot,
652 _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY,
653 fNameW.ToWideString());
7fd59977 654
fb0b0531 655 if (pSD == NULL || !SetFileSecurityW (fNameW.ToWideString(), DACL_SECURITY_INFORMATION, pSD))
656 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
7fd59977 657
658 if ( pSD != NULL )
659
660 FreeSD ( pSD );
661
662} // end OSD_FileNode :: SetProtection
663
742cc8b0 664#else /* UWP stub */
665
666#include <io.h>
667
668//=======================================================================
669//function : Protection
670//purpose :
671//=======================================================================
672
673OSD_Protection OSD_FileNode::Protection ()
674{
675 TCollection_AsciiString fName;
676
677 myPath.SystemName ( fName );
678 TCollection_ExtendedString fNameW(fName);
679
680 OSD_SingleProtection aProt = OSD_None;
fb0b0531 681 if (_waccess_s (fNameW.ToWideString(), 6))
742cc8b0 682 aProt = OSD_RW;
fb0b0531 683 else if (_waccess_s (fNameW.ToWideString(), 2))
742cc8b0 684 aProt = OSD_W;
fb0b0531 685 else if (_waccess_s (fNameW.ToWideString(), 4))
742cc8b0 686 aProt = OSD_R;
687
688 // assume full access for system and none for everybody
689 OSD_Protection retVal (OSD_RWXD, aProt, aProt, OSD_None);
690 return retVal;
691} // end OSD_FileNode :: Protection
692
693//=======================================================================
694//function : SetProtection
695//purpose :
696//=======================================================================
697
698void OSD_FileNode::SetProtection ( const OSD_Protection& /*Prot*/ )
699{
700} // end OSD_FileNode :: SetProtection
701
702#endif
703
7fd59977 704//=======================================================================
705//function : AccessMoment
706//purpose :
707//=======================================================================
708
709Quantity_Date OSD_FileNode::AccessMoment () {
710
711 Quantity_Date retVal;
712 SYSTEMTIME stAccessMoment;
713 SYSTEMTIME stAccessSystemMoment;
714 TCollection_AsciiString fName;
715
716 myPath.SystemName ( fName );
d9ff84e8 717 TCollection_ExtendedString fNameW(fName);
7fd59977 718
d9ff84e8 719 TEST_RAISE( "AccessMoment" );
7fd59977 720
fb0b0531 721 if (_get_file_time (fNameW.ToWideString(), &stAccessSystemMoment, TRUE))
7fd59977 722{
723 SYSTEMTIME * aSysTime = &stAccessMoment;
724 BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL ,
725 &stAccessSystemMoment ,
726 &stAccessMoment);
727 if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
728 aSysTime = &stAccessSystemMoment;
729 retVal.SetValues (aSysTime->wMonth, aSysTime->wDay,
730 aSysTime->wYear, aSysTime->wHour,
731 aSysTime->wMinute, aSysTime->wSecond,
732 aSysTime->wMilliseconds
733 );
734}
735 else
fb0b0531 736 {
737 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
738 }
7fd59977 739
740 return retVal;
741
742} // end OSD_FileNode :: AccessMoment
743
744//=======================================================================
745//function : CreationMoment
746//purpose :
747//=======================================================================
748
749Quantity_Date OSD_FileNode::CreationMoment () {
750
751 Quantity_Date retVal;
752 SYSTEMTIME stCreationMoment;
753 SYSTEMTIME stCreationSystemMoment;
754 TCollection_AsciiString fName;
755
756 myPath.SystemName ( fName );
d9ff84e8 757 TCollection_ExtendedString fNameW(fName);
7fd59977 758
d9ff84e8 759 TEST_RAISE( "CreationMoment" );
7fd59977 760
04c5a696 761 if (_get_file_time (fNameW.ToWideString(), &stCreationSystemMoment, FALSE))
7fd59977 762{
763 SYSTEMTIME * aSysTime = &stCreationMoment;
764 BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL,
765 &stCreationSystemMoment ,
766 &stCreationMoment);
767 if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
768 aSysTime = &stCreationSystemMoment;
769 retVal.SetValues (aSysTime->wMonth, aSysTime->wDay,
770 aSysTime->wYear, aSysTime->wHour,
771 aSysTime->wMinute, aSysTime->wSecond,
772 aSysTime->wMilliseconds
773 );
774}
775 else
fb0b0531 776 {
777 _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
778 }
7fd59977 779
780 return retVal;
781
782} // end OSD_FileNode :: CreationMoment
783
784//=======================================================================
7fd59977 785//function : Failed
786//purpose :
787//=======================================================================
788
789Standard_Boolean OSD_FileNode::Failed () const {
790
791 return myError.Failed ();
792
793} // end OSD_FileNode :: Failed
794
795//=======================================================================
796//function : Reset
797//purpose :
798//=======================================================================
799
800void OSD_FileNode::Reset () {
801
802 myError.Reset ();
803
804} // end OSD_FileNode :: Reset
805
806//=======================================================================
807//function : Perror
808//purpose :
809//=======================================================================
810
811void OSD_FileNode::Perror () {
812
813 myError.Perror ();
814
815} // end OSD_FileNode :: Perror
816
817//=======================================================================
818//function : Error
819//purpose :
820//=======================================================================
821
822Standard_Integer OSD_FileNode::Error () const {
823
824 return myError.Error ();
825
826} // end OSD_FileNode :: Error
827
1bd04b5a 828void _osd_wnt_set_error ( OSD_Error& err, Standard_Integer who, ... ) {
7fd59977 829
830 DWORD errCode;
742cc8b0 831
832 wchar_t buffer[2048];
833
7fd59977 834 va_list arg_ptr;
835
9bfa28a7 836 va_start ( arg_ptr, who);
7fd59977 837
838 errCode = GetLastError ();
839
742cc8b0 840 if ( !FormatMessageW (
841 FORMAT_MESSAGE_FROM_SYSTEM,
7fd59977 842 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
843 buffer, 2048, &arg_ptr
844 )
845 ) {
742cc8b0 846 StringCchPrintfW(buffer, _countof(buffer), L"error code %d", (Standard_Integer)errCode);
847
7fd59977 848 SetLastError ( errCode );
849
850 } // end if
851
742cc8b0 852 char aBufferA[2048];
853 WideCharToMultiByte(CP_UTF8, 0, buffer, -1, aBufferA, sizeof(aBufferA), NULL, NULL);
854 err.SetValue(errCode, who, aBufferA);
7fd59977 855
856 va_end ( arg_ptr );
857
858} // end _set_error
859
860#if defined(__CYGWIN32__) || defined(__MINGW32__)
cda06ac0 861#ifdef __try /* is defined on MinGw as either "try" or "if (true)" */
862#undef __try
863#endif
7fd59977 864#define __try
865#define __finally
866#define __leave return retVal
867#endif
868
fb0b0531 869static BOOL __fastcall _get_file_time (const wchar_t* fName, LPSYSTEMTIME lpSysTime, BOOL fAccess)
870{
7fd59977 871 BOOL retVal = FALSE;
872 FILETIME ftCreationTime;
873 FILETIME ftLastWriteTime;
874 LPFILETIME lpftPtr;
302f96fb 875 HANDLE hFile = INVALID_HANDLE_VALUE;
7fd59977 876
877 __try {
742cc8b0 878#ifndef OCCT_UWP
fb0b0531 879 if ((hFile = CreateFileW (fName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)
742cc8b0 880 ) == INVALID_HANDLE_VALUE
881 )
882#else
883 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams = {};
884 pCreateExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
885 pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
886 pCreateExParams.lpSecurityAttributes = NULL;
887 pCreateExParams.hTemplateFile = NULL;
fb0b0531 888 if ((hFile = CreateFile2 (fName, NULL, NULL, OPEN_EXISTING, &pCreateExParams)) == INVALID_HANDLE_VALUE)
742cc8b0 889#endif
890 __leave;
7fd59977 891
892 if ( !GetFileTime ( hFile, &ftCreationTime, NULL, &ftLastWriteTime ) ) __leave;
893
894 lpftPtr = fAccess ? &ftLastWriteTime : &ftCreationTime;
895
896 if ( !FileTimeToSystemTime ( lpftPtr, lpSysTime ) ) __leave;
897
898 retVal = TRUE;
899
900 } // end __try
901
902 __finally {
903
904 if ( hFile != INVALID_HANDLE_VALUE )
905
906 CloseHandle ( hFile );
907
908 } // end __finally
909
7fd59977 910 return retVal;
911
912} // end _get_file_time
913
914#if defined(__CYGWIN32__) || defined(__MINGW32__)
915#undef __try
916#undef __finally
917#undef __leave
918#endif
919
920static void __fastcall _test_raise ( TCollection_AsciiString fName, Standard_CString str ) {
7fd59977 921 if ( fName.IsEmpty () ) {
742cc8b0 922 TCollection_AsciiString buff = "OSD_FileNode :: ";
923 buff += str;
924 buff += " (): wrong access";
7fd59977 925
9775fa61 926 throw Standard_ProgramError(buff.ToCString());
7fd59977 927 } // end if
928
929} // end _test_raise
930
6ff736d8 931#endif /* _WIN32 */