0030091: Configuration - allow cross-compilation from Linux (case sensitive filesyste...
[occt.git] / src / OSD / OSD_File.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
cda06ac0 15#ifdef _WIN32
16 #include <windows.h>
17#endif
42cf5bc1 18
19#include <OSD_File.hxx>
cda06ac0 20
21#include <NCollection_Array1.hxx>
22#include <OSD.hxx>
7fd59977 23#include <OSD_OSDError.hxx>
42cf5bc1 24#include <OSD_Path.hxx>
42cf5bc1 25#include <OSD_Protection.hxx>
7fd59977 26#include <OSD_WhoAmI.hxx>
42cf5bc1 27#include <Standard_ProgramError.hxx>
cda06ac0 28#include <TCollection_ExtendedString.hxx>
7fd59977 29
cda06ac0 30#ifdef _WIN32
7fd59977 31
68df8478 32 #include <OSD_WNT.hxx>
7fd59977 33
cda06ac0 34 #include <stdio.h>
35 #include <io.h>
7fd59977 36
5fecc495 37 #include <strsafe.h>
7fd59977 38
cda06ac0 39 #define ACE_HEADER_SIZE (sizeof(ACCESS_ALLOWED_ACE) - sizeof (DWORD))
7fd59977 40
cda06ac0 41 #define OPEN_NEW 0
42 #define OPEN_OLD 1
43 #define OPEN_APPEND 2
7fd59977 44
cda06ac0 45 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
7fd59977 46
cda06ac0 47#ifndef OCCT_UWP
48 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, const wchar_t* );
49 BOOL __fastcall _osd_wnt_sd_to_protection (PSECURITY_DESCRIPTOR, OSD_Protection&, BOOL);
50
51 static int OSD_File_getBuffer (HANDLE theChannel,
52 char* theBuffer,
53 DWORD theSize,
54 BOOL theIsPeek,
55 BOOL theIsSocket)
56 {
57 if (theIsSocket)
58 {
59 const int aFlags = theIsPeek ? MSG_PEEK : 0;
60 const int aRetVal = recv ((SOCKET )theChannel, theBuffer, (int )theSize, aFlags);
61 return aRetVal != SOCKET_ERROR
62 ? aRetVal
63 : -1;
64 }
7fd59977 65
cda06ac0 66 DWORD aBytesRead = 0;
67 if (theIsPeek)
68 {
69 DWORD aDummy = 0;
70 if (!PeekNamedPipe (theChannel, theBuffer, theSize, &aBytesRead, &aDummy, &aDummy)
71 && GetLastError() != ERROR_BROKEN_PIPE)
72 {
73 return -1;
74 }
75 return (int )aBytesRead;
76 }
77 else if (!ReadFile (theChannel, theBuffer, theSize, &aBytesRead, NULL))
78 {
79 return -1;
80 }
81 return (int )aBytesRead;
82 }
7fd59977 83
cda06ac0 84 static OSD_SingleProtection OSD_File_getProtection (DWORD theMask)
85 {
86 switch (theMask)
87 {
88 case FILE_GENERIC_READ:
89 return OSD_R;
90 case FILE_GENERIC_WRITE:
91 return OSD_W;
92 case FILE_GENERIC_READ | FILE_GENERIC_WRITE:
93 return OSD_RW;
94 case FILE_GENERIC_EXECUTE:
95 return OSD_X;
96 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE:
97 return OSD_RX;
98 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
99 return OSD_WX;
100 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
101 return OSD_RWX;
102 case DELETE:
103 return OSD_D;
104 case FILE_GENERIC_READ | DELETE:
105 return OSD_RD;
106 case FILE_GENERIC_WRITE | DELETE:
107 return OSD_WD;
108 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE:
109 return OSD_RWD;
110 case FILE_GENERIC_EXECUTE | DELETE:
111 return OSD_XD;
112 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE:
113 return OSD_RXD;
114 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
115 return OSD_WXD;
116 case FILE_ALL_ACCESS:
117 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
118 return OSD_RWXD;
119 }
120 return OSD_None;
121 }
7fd59977 122
cda06ac0 123 static OSD_SingleProtection OSD_File_getProtectionDir (DWORD theMask)
124 {
125 switch (theMask)
126 {
127 case GENERIC_READ:
128 return OSD_R;
129 case GENERIC_WRITE:
130 return OSD_W;
131 case GENERIC_READ | GENERIC_WRITE:
132 return OSD_RW;
133 case GENERIC_EXECUTE:
134 return OSD_X;
135 case GENERIC_READ | GENERIC_EXECUTE:
136 return OSD_RX;
137 case GENERIC_WRITE | GENERIC_EXECUTE:
138 return OSD_WX;
139 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE:
140 return OSD_RWX;
141 case DELETE:
142 return OSD_D;
143 case GENERIC_READ | DELETE:
144 return OSD_RD;
145 case GENERIC_WRITE | DELETE:
146 return OSD_WD;
147 case GENERIC_READ | GENERIC_WRITE | DELETE:
148 return OSD_RWD;
149 case GENERIC_EXECUTE | DELETE:
150 return OSD_XD;
151 case GENERIC_READ | GENERIC_EXECUTE | DELETE:
152 return OSD_RXD;
153 case GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
154 return OSD_WXD;
155 case FILE_ALL_ACCESS:
156 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
157 return OSD_RWXD;
158 case 0:
159 return OSD_None;
160 default:
161 // remote directories (on Samba server) have flags like for files
162 return OSD_File_getProtection (theMask);
163 }
164 }
7fd59977 165
cda06ac0 166 static DWORD OSD_File_getAccessMask (OSD_SingleProtection theProtection)
167 {
168 switch (theProtection)
169 {
170 case OSD_None: return 0;
171 case OSD_R: return FILE_GENERIC_READ;
172 case OSD_W: return FILE_GENERIC_WRITE;
173 case OSD_RW: return FILE_GENERIC_READ | FILE_GENERIC_WRITE;
174 case OSD_X: return FILE_GENERIC_EXECUTE;
175 case OSD_RX: return FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
176 case OSD_WX: return FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
177 case OSD_RWX: return FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
178 case OSD_D: return DELETE;
179 case OSD_RD: return FILE_GENERIC_READ | DELETE;
180 case OSD_WD: return FILE_GENERIC_WRITE | DELETE;
181 case OSD_RWD: return FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
182 case OSD_XD: return FILE_GENERIC_EXECUTE | DELETE;
183 case OSD_RXD: return FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE;
184 case OSD_WXD: return FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
185 case OSD_RWXD: return FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
186 }
187 throw Standard_ProgramError ("OSD_File_getAccessMask(): incorrect parameter");
188 }
7fd59977 189
cda06ac0 190 static DWORD OSD_File_getDirAccessMask (OSD_SingleProtection theProtection)
191 {
192 switch (theProtection)
193 {
194 case OSD_None: return 0;
195 case OSD_R: return GENERIC_READ;
196 case OSD_W: return GENERIC_WRITE;
197 case OSD_RW: return GENERIC_READ | GENERIC_WRITE;
198 case OSD_X: return GENERIC_EXECUTE;
199 case OSD_RX: return GENERIC_READ | GENERIC_EXECUTE;
200 case OSD_WX: return GENERIC_WRITE | GENERIC_EXECUTE;
201 case OSD_RWX: return GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE;
202 case OSD_D: return DELETE;
203 case OSD_RD: return GENERIC_READ | DELETE;
204 case OSD_WD: return GENERIC_WRITE | DELETE;
205 case OSD_RWD: return GENERIC_READ | GENERIC_WRITE | DELETE;
206 case OSD_XD: return GENERIC_EXECUTE | DELETE;
207 case OSD_RXD: return GENERIC_READ | GENERIC_EXECUTE | DELETE;
208 case OSD_WXD: return GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
209 case OSD_RWXD: return GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
210 }
211 throw Standard_ProgramError ("OSD_File_getDirAccessMask(): incorrect parameter");
212 }
7fd59977 213
cda06ac0 214 struct OSD_File_WntKey
215 {
216 HKEY hKey;
217 const wchar_t* keyPath;
218 };
7fd59977 219
cda06ac0 220 #endif /* ! OCCT_UWP */
7fd59977 221
cda06ac0 222 Standard_Integer __fastcall _get_file_type (Standard_CString theFileName,
223 HANDLE theFileHandle)
224 {
225 const int aFileType = theFileHandle == INVALID_HANDLE_VALUE
226 ? FILE_TYPE_DISK
227 : GetFileType (theFileHandle);
228 switch (aFileType)
229 {
230 case FILE_TYPE_UNKNOWN:
231 return FLAG_SOCKET;
232 case FILE_TYPE_DISK:
233 {
234 const TCollection_ExtendedString aFileNameW (theFileName, Standard_True);
235 WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
236 if (GetFileAttributesExW (aFileNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
237 {
238 return aFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FLAG_DIRECTORY : FLAG_FILE;
239 }
240 return 0x80000000;
241 }
242 case FILE_TYPE_CHAR:
243 return FLAG_DEVICE;
244 case FILE_TYPE_PIPE:
245 return FLAG_PIPE;
246 }
247 return 0;
248 }
7fd59977 249
cda06ac0 250 //! Returns number of bytes in the string (including end \n, but excluding \r);
251 static Standard_Integer OSD_File_getLine (char* theBuffer, DWORD theBuffSize, LONG& theSeekPos)
252 {
253 theBuffer[theBuffSize] = 0;
254 for (char* aCharIter = theBuffer; *aCharIter != 0; )
255 {
256 if (*aCharIter == '\n')
257 {
258 ++aCharIter; // jump newline char
259 *aCharIter = '\0';
260 theSeekPos = LONG(aCharIter - theBuffer - theBuffSize);
261 return Standard_Integer(aCharIter - theBuffer);
262 }
263 else if (aCharIter[0] == '\r'
264 && aCharIter[1] == '\n')
265 {
266 *(aCharIter++) = '\n'; // Substitute carriage return by newline
267 *aCharIter = 0;
268 theSeekPos = LONG(aCharIter + 1 - theBuffer - theBuffSize);
269 return Standard_Integer(aCharIter - theBuffer);
270 }
271 else if (aCharIter[0] == '\r'
272 && aCharIter[1] == '\0')
273 {
274 *aCharIter = '\n' ; // Substitute carriage return by newline
275 return -1;
276 }
277 ++aCharIter;
278 }
7fd59977 279
cda06ac0 280 theSeekPos = 0;
281 return theBuffSize;
282 }
7fd59977 283
cda06ac0 284 static HANDLE OSD_File_openFile (const TCollection_AsciiString& theFileName,
285 OSD_OpenMode theOpenMode,
286 DWORD theOptions, bool* theIsNew = NULL)
287 {
288 DWORD dwDesiredAccess = 0;
289 switch (theOpenMode)
290 {
291 case OSD_ReadOnly:
292 dwDesiredAccess = GENERIC_READ;
293 break;
294 case OSD_WriteOnly:
295 dwDesiredAccess = GENERIC_WRITE;
296 break;
297 case OSD_ReadWrite:
298 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
299 break;
300 default:
301 throw Standard_ProgramError ("OSD_File_openFile(): incorrect parameter");
302 }
7fd59977 303
cda06ac0 304 DWORD dwCreationDistribution = (theOptions != OPEN_NEW) ? OPEN_EXISTING : CREATE_ALWAYS;
305 const TCollection_ExtendedString aFileNameW (theFileName);
306 #ifndef OCCT_UWP
307 HANDLE aFileHandle = CreateFileW (aFileNameW.ToWideString(), dwDesiredAccess,
308 FILE_SHARE_READ | FILE_SHARE_WRITE,
309 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL);
310 #else
311 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams = {};
312 pCreateExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
313 pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
314 pCreateExParams.lpSecurityAttributes = NULL;
315 pCreateExParams.hTemplateFile = NULL;
316 HANDLE aFileHandle = CreateFile2 (aFileNameW.ToWideString(), dwDesiredAccess,
317 FILE_SHARE_READ | FILE_SHARE_WRITE,
318 dwCreationDistribution, &pCreateExParams);
319 #endif
320 if (aFileHandle != INVALID_HANDLE_VALUE
321 || theOptions != OPEN_APPEND
322 || GetLastError() != ERROR_FILE_NOT_FOUND)
323 {
324 return aFileHandle;
325 }
7fd59977 326
cda06ac0 327 dwCreationDistribution = CREATE_ALWAYS;
328 #ifndef OCCT_UWP
329 aFileHandle = CreateFileW (aFileNameW.ToWideString(), dwDesiredAccess,
330 FILE_SHARE_READ | FILE_SHARE_WRITE,
331 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL );
332 #else
333 CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams2 = {};
334 pCreateExParams2.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
335 pCreateExParams2.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
336 pCreateExParams2.lpSecurityAttributes = NULL;
337 pCreateExParams2.hTemplateFile = NULL;
338 aFileHandle = CreateFile2 (aFileNameW.ToWideString(), dwDesiredAccess,
339 FILE_SHARE_READ | FILE_SHARE_WRITE,
340 dwCreationDistribution, &pCreateExParams2 );
341 #endif
342 *theIsNew = true;
343 return aFileHandle;
344 }
7fd59977 345
cda06ac0 346#else
7fd59977 347
cda06ac0 348 const OSD_WhoAmI Iam = OSD_WFile;
7fd59977 349
cda06ac0 350 #if defined (sun) || defined(SOLARIS)
351 #define POSIX
352 #else
353 #define SYSV
354 #endif
7fd59977 355
cda06ac0 356 #include <errno.h>
357 #include <stdlib.h>
358 #include <stdio.h>
359 #include <fcntl.h>
360 #include <unistd.h>
361 #include <sys/stat.h>
7fd59977 362
cda06ac0 363 #define NEWLINE '\10';
364#endif
7fd59977 365
cda06ac0 366// =======================================================================
367// function : OSD_File
368// purpose :
369// =======================================================================
370OSD_File::OSD_File() :
371#ifdef _WIN32
372 myFileHandle (INVALID_HANDLE_VALUE),
373#else
374 myFileChannel (-1),
375#endif
376 myFILE (NULL),
377 myIO (0),
378 myLock (OSD_NoLock),
379 myMode (OSD_ReadWrite),
380 ImperativeFlag (Standard_False)
381{
382 //
383}
7fd59977 384
cda06ac0 385// =======================================================================
386// function : OSD_File
387// purpose :
388// =======================================================================
389OSD_File::OSD_File (const OSD_Path& theName)
390: OSD_FileNode (theName),
391#ifdef _WIN32
392 myFileHandle (INVALID_HANDLE_VALUE),
393#else
394 myFileChannel (-1),
395#endif
396 myFILE (NULL),
397 myIO (0),
398 myLock (OSD_NoLock),
399 myMode (OSD_ReadWrite),
400 ImperativeFlag (Standard_False)
401{
402 //
403}
7fd59977 404
cda06ac0 405// =======================================================================
406// function : ~OSD_File
407// purpose :
408// =======================================================================
409OSD_File::~OSD_File()
410{
411 if (IsOpen())
412 {
413 if (IsLocked())
414 {
415 UnLock();
416 }
417 Close();
418 }
419}
7fd59977 420
cda06ac0 421// =======================================================================
422// function : Build
423// purpose :
424// =======================================================================
425void OSD_File::Build (const OSD_OpenMode theMode,
426 const OSD_Protection& theProtect)
427{
428 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
429 {
430 throw Standard_ProgramError ("OSD_File::Build(): it is a directory");
431 }
432 if (IsOpen())
433 {
434 throw Standard_ProgramError ("OSD_File::Build(): incorrect call - file already opened");
435 }
7fd59977 436
cda06ac0 437 TCollection_AsciiString aFileName;
438 myPath.SystemName (aFileName);
439#ifdef _WIN32
440 if (aFileName.IsEmpty())
441 {
442 throw Standard_ProgramError ("OSD_File::Build(): incorrect call - no filename given");
443 }
7fd59977 444
cda06ac0 445 myMode = theMode;
446 myFileHandle = OSD_File_openFile (aFileName, theMode, OPEN_NEW);
447 if (myFileHandle == INVALID_HANDLE_VALUE)
448 {
449 _osd_wnt_set_error (myError, OSD_WFile);
450 }
451 else
452 {
453 #ifndef OCCT_UWP
454 SetProtection (theProtect);
455 #else
456 (void)theProtect;
457 #endif
458 myIO |= FLAG_FILE;
459 }
460#else
461 if (myPath.Name().Length() == 0)
462 {
463 throw Standard_ProgramError ("OSD_File::Build(): no name was given");
464 }
7fd59977 465
cda06ac0 466 const char* anFDOpenMode = "r";
467 Standard_Integer anOpenMode = O_CREAT | O_TRUNC;
468 switch (theMode)
469 {
470 case OSD_ReadOnly:
471 anOpenMode |= O_RDONLY;
472 anFDOpenMode = "r";
473 break;
474 case OSD_WriteOnly:
475 anOpenMode |= O_WRONLY;
476 anFDOpenMode = "w";
477 break;
478 case OSD_ReadWrite:
479 anOpenMode |= O_RDWR;
480 anFDOpenMode = "w+";
481 break;
482 }
7fd59977 483
cda06ac0 484 myMode = theMode;
485 myFileChannel = open (aFileName.ToCString(), anOpenMode, theProtect.Internal());
486 if (myFileChannel >= 0)
487 {
488 myFILE = fdopen (myFileChannel, anFDOpenMode);
489 }
490 else
491 {
492 myError.SetValue (errno, Iam, "Open");
493 }
494#endif
7fd59977 495}
496
cda06ac0 497// =======================================================================
498// function : Append
499// purpose :
500// =======================================================================
501void OSD_File::Append (const OSD_OpenMode theMode,
502 const OSD_Protection& theProtect)
503{
504 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
505 {
506 throw Standard_ProgramError ("OSD_File::Append(): it is a directory");
507 }
508 if (IsOpen())
509 {
510 throw Standard_ProgramError ("OSD_File::Append(): incorrect call - file already opened");
511 }
7fd59977 512
cda06ac0 513 TCollection_AsciiString aFileName;
514 myPath.SystemName (aFileName);
515#ifdef _WIN32
516 if (aFileName.IsEmpty())
517 {
518 throw Standard_ProgramError ("OSD_File::Append(): incorrect call - no filename given");
519 }
7fd59977 520
cda06ac0 521 bool isNewFile = false;
522 myMode = theMode;
523 myFileHandle = OSD_File_openFile (aFileName, theMode, OPEN_APPEND, &isNewFile);
524 if (myFileHandle == INVALID_HANDLE_VALUE)
525 {
526 _osd_wnt_set_error (myError, OSD_WFile);
527 }
528 else
529 {
530 if (!isNewFile)
531 {
532 myIO |= _get_file_type (aFileName.ToCString(), myFileHandle);
533 Seek (0, OSD_FromEnd);
534 }
535 else
536 {
537 #ifndef OCCT_UWP
538 SetProtection (theProtect);
539 #else
540 (void)theProtect;
541 #endif
542 myIO |= FLAG_FILE;
543 }
544 }
545#else
546 if (myPath.Name().Length() == 0)
547 {
548 throw Standard_ProgramError ("OSD_File::Append(): no name was given");
549 }
95e05159 550
cda06ac0 551 const char* anFDOpenMode = "r";
552 Standard_Integer anOpenMode = O_APPEND;
553 switch (theMode)
554 {
555 case OSD_ReadOnly:
556 anOpenMode |= O_RDONLY;
557 anFDOpenMode = "r";
558 break;
559 case OSD_WriteOnly:
560 anOpenMode |= O_WRONLY;
561 anFDOpenMode = "a";
562 break;
563 case OSD_ReadWrite:
564 anOpenMode |= O_RDWR;
565 anFDOpenMode = "a+";
566 break;
567 }
7fd59977 568
cda06ac0 569 if (!Exists())
570 {
571 // if file doesn't exist, creates it
572 anOpenMode |= O_CREAT;
573 }
7fd59977 574
cda06ac0 575 myMode = theMode;
576 myFileChannel = open (aFileName.ToCString(), anOpenMode, theProtect.Internal());
577 if (myFileChannel >= 0)
578 {
579 myFILE = fdopen (myFileChannel, anFDOpenMode);
580 }
581 else
582 {
583 myError.SetValue (errno, Iam, "Open");
584 }
585#endif
586}
7fd59977 587
cda06ac0 588// =======================================================================
589// function : Open
590// purpose :
591// =======================================================================
592void OSD_File::Open (const OSD_OpenMode theMode,
593 const OSD_Protection& theProtect)
594{
595 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
596 {
597 throw Standard_ProgramError ("OSD_File::Open(): it is a directory");
598 }
599 if (IsOpen())
600 {
601 throw Standard_ProgramError ("OSD_File::Open(): incorrect call - file already opened");
602 }
7fd59977 603
cda06ac0 604 TCollection_AsciiString aFileName;
605 myPath.SystemName (aFileName);
606#ifdef _WIN32
607 if (aFileName.IsEmpty())
608 {
609 throw Standard_ProgramError ("OSD_File::Open(): incorrect call - no filename given");
610 }
7fd59977 611
cda06ac0 612 (void )theProtect;
613 myMode = theMode;
614 myFileHandle = OSD_File_openFile (aFileName, theMode, OPEN_OLD);
615 if (myFileHandle == INVALID_HANDLE_VALUE)
616 {
617 _osd_wnt_set_error (myError, OSD_WFile);
618 }
619 else
620 {
621 myIO |= _get_file_type (aFileName.ToCString(), myFileHandle);
622 }
623#else
624 if (myPath.Name().Length() == 0)
625 {
626 throw Standard_ProgramError ("OSD_File::Open(): no name was given");
627 }
7fd59977 628
cda06ac0 629 const char* anFDOpenMode = "r";
630 Standard_Integer anOpenMode = 0;
631 switch (theMode)
632 {
633 case OSD_ReadOnly:
634 anOpenMode |= O_RDONLY;
635 anFDOpenMode = "r";
636 break;
637 case OSD_WriteOnly:
638 anOpenMode |= O_WRONLY;
639 anFDOpenMode = "w";
640 break;
641 case OSD_ReadWrite:
642 anOpenMode |= O_RDWR;
643 anFDOpenMode = "w+";
644 break;
645 }
7fd59977 646
cda06ac0 647 myMode = theMode;
648 myFileChannel = open (aFileName.ToCString(), anOpenMode, theProtect.Internal());
649 if (myFileChannel >= 0)
650 {
651 myFILE = fdopen (myFileChannel, anFDOpenMode);
652 }
653 else
654 {
655 myError.SetValue (errno, Iam, "Open");
656 }
7fd59977 657#endif
7fd59977 658}
7fd59977 659
cda06ac0 660// =======================================================================
661// function : BuildTemporary
662// purpose :
663// =======================================================================
664void OSD_File::BuildTemporary()
665{
666#ifdef _WIN32
7fd59977 667
cda06ac0 668 TCollection_ExtendedString aTmpFolderW;
669 BOOL fOK = FALSE;
670#ifndef OCCT_UWP
671 const OSD_File_WntKey TheRegKeys[2] =
672 {
673 { HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment" },
674 { HKEY_USERS, L".DEFAULT\\Environment" }
675 };
676 for (int aKeyIter = 0; aKeyIter < 2; ++aKeyIter)
677 {
678 HKEY aRegKey = NULL;
679 if (RegOpenKeyExW (TheRegKeys[aKeyIter].hKey, TheRegKeys[aKeyIter].keyPath, 0, KEY_QUERY_VALUE, &aRegKey) != ERROR_SUCCESS)
680 {
681 continue;
682 }
7fd59977 683
cda06ac0 684 DWORD aKeyType = 0, aKeySize = 0;
685 if (RegQueryValueExW (aRegKey, L"TEMP", NULL, &aKeyType, NULL, &aKeySize) == ERROR_SUCCESS)
686 {
687 NCollection_Array1<wchar_t> aKeyValW (0, aKeySize);
688 RegQueryValueExW (aRegKey, L"TEMP", NULL, &aKeyType, (LPBYTE )&aKeyValW.ChangeFirst(), &aKeySize);
689 if (aKeyType == REG_EXPAND_SZ)
690 {
691 wchar_t aTmpBuffer[MAX_PATH];
692 ExpandEnvironmentStringsW (&aKeyValW.First(), aTmpBuffer, MAX_PATH);
693 aTmpFolderW = TCollection_ExtendedString (aTmpBuffer);
694 }
695 else
696 {
697 aTmpFolderW = TCollection_ExtendedString (&aKeyValW.First());
698 }
699 fOK = TRUE;
700 }
701 RegCloseKey (aRegKey);
702 if (fOK) break;
703 }
704#else
705 // Windows Registry not supported by UWP
706 {
707 wchar_t aTmpBuffer[MAX_PATH];
708 fOK = GetTempPathW (_countof(aTmpBuffer), aTmpBuffer) != 0;
709 aTmpFolderW = TCollection_ExtendedString (aTmpBuffer);
710 }
711#endif
712 if (!fOK)
713 {
714 aTmpFolderW = "./";
7fd59977 715 }
716
cda06ac0 717 wchar_t aTmpPathW[MAX_PATH];
718 GetTempFileNameW (aTmpFolderW.ToWideString(), L"CSF", 0, aTmpPathW);
719 if (IsOpen())
720 {
721 Close();
722 }
7fd59977 723
cda06ac0 724 SetPath (OSD_Path (TCollection_AsciiString (aTmpPathW)));
725 Build (OSD_ReadWrite, OSD_Protection());
7fd59977 726
cda06ac0 727#else /* _WIN32 */
7fd59977 728
cda06ac0 729 if (IsOpen())
730 {
731 Close();
732 }
733#if defined(vax) || defined(__vms) || defined(VAXVMS)
734 FILE* fic = tmpfile();
735 int dummy = open("dummy", O_RDWR | O_CREAT); // open a dummy file
736 myFileChannel = dummy - 1; // this is file channel of "fic" +1
737 close (dummy); // close dummy file
738 unlink ("dummy"); // removes dummy file
739#else
740 char aTmpName[] = "/tmp/CSFXXXXXX";
741 myFileChannel = mkstemp (aTmpName);
742 const TCollection_AsciiString aName (aTmpName);
743 const OSD_Path aPath (aName);
744 SetPath (aPath);
745 myFILE = fdopen (myFileChannel, "w+");
746#endif
747 myMode = OSD_ReadWrite;
7fd59977 748
cda06ac0 749#endif
7fd59977 750}
751
cda06ac0 752// =======================================================================
753// function : Read
754// purpose :
755// =======================================================================
756void OSD_File::Read (TCollection_AsciiString& theBuffer,
757 const Standard_Integer theNbBytes)
7fd59977 758{
cda06ac0 759 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
760 {
761 throw Standard_ProgramError ("OSD_File::Read(): it is a directory");
7fd59977 762 }
cda06ac0 763 if (!IsOpen())
764 {
765 throw Standard_ProgramError ("OSD_File::Read(): file is not open");
7fd59977 766 }
cda06ac0 767 if (Failed())
768 {
7fd59977 769 Perror();
770 }
cda06ac0 771 if (myMode == OSD_WriteOnly)
772 {
773 throw Standard_ProgramError ("OSD_File::Read(): file is Write only");
7fd59977 774 }
cda06ac0 775 if (theNbBytes <= 0)
776 {
777 throw Standard_ProgramError ("OSD_File::Read(): theNbBytes is 0");
7fd59977 778 }
cda06ac0 779
780 NCollection_Array1<char> aBuffer (0, theNbBytes);
781 Standard_Integer aNbBytesRead = 0;
782#ifdef _WIN32
783 Read (&aBuffer.ChangeFirst(), theNbBytes, aNbBytesRead);
784#else
785 aNbBytesRead = read (myFileChannel, &aBuffer.ChangeFirst(), theNbBytes);
786 if (aNbBytesRead == -1)
787 {
788 aNbBytesRead = 0;
789 myError.SetValue (errno, Iam, "Read");
7fd59977 790 }
cda06ac0 791 else if (aNbBytesRead < theNbBytes)
792 {
793 myIO = EOF;
794 }
795#endif
796 if (aNbBytesRead != 0)
797 {
798 aBuffer.ChangeValue (aNbBytesRead) = '\0';
799 theBuffer = &aBuffer.First();
800 }
801 else
802 {
803 theBuffer.Clear();
7fd59977 804 }
805}
7fd59977 806
cda06ac0 807// =======================================================================
808// function : ReadLine
809// purpose :
810// =======================================================================
811void OSD_File::ReadLine (TCollection_AsciiString& theBuffer,
812 const Standard_Integer theNbBytes,
813 Standard_Integer& theNbBytesRead)
7fd59977 814{
cda06ac0 815 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
816 {
817 throw Standard_ProgramError ("OSD_File::ReadLine(): it is a directory");
818 }
819 if (!IsOpen())
820 {
821 throw Standard_ProgramError ("OSD_File::ReadLine(): file is not open");
822 }
823 if (Failed())
824 {
825 Perror();
826 }
7fd59977 827 if (myMode == OSD_WriteOnly)
cda06ac0 828 {
829 throw Standard_ProgramError ("OSD_File::ReadLine(): file is Write only");
830 }
831 if (theNbBytes <= 0)
832 {
833 throw Standard_ProgramError ("OSD_File::ReadLine(): theNbBytes is 0");
834 }
835#ifdef _WIN32
836 if (myIO & FLAG_PIPE && !(myIO & FLAG_READ_PIPE))
837 {
838 throw Standard_ProgramError ("OSD_File::ReadLine(): attempt to read from write only pipe");
7fd59977 839 }
7fd59977 840
cda06ac0 841 DWORD aNbBytesRead = 0;
842 LONG aSeekPos = 0;
843 char aPeekChar = '\0';
844 // +----> leave space for end-of-string
845 // | plus <CR><LF> sequence
846 // |
847 NCollection_Array1<char> aBuffer (0, theNbBytes + 2);
848 if (myIO & FLAG_FILE)
849 {
850 if (!ReadFile (myFileHandle, &aBuffer.ChangeFirst(), theNbBytes, &aNbBytesRead, NULL))
851 {
852 _osd_wnt_set_error (myError, OSD_WFile);
853 theBuffer.Clear();
854 theNbBytesRead = 0;
855 }
856 else if (aNbBytesRead == 0)
857 {
858 theBuffer.Clear();
859 theNbBytesRead = 0;
860 myIO |= FLAG_EOF;
861 }
862 else
863 {
864 myIO &= ~FLAG_EOF; // if the file increased since last read (LD)
865 theNbBytesRead = OSD_File_getLine (&aBuffer.ChangeFirst(), aNbBytesRead, aSeekPos);
866 if (theNbBytesRead == -1) // last character in the buffer is <CR> -
867 { // peek next character to see if it is a <LF>
868 DWORD dwDummy = 0;
869 if (!ReadFile (myFileHandle, &aPeekChar, 1, &dwDummy, NULL))
870 {
871 _osd_wnt_set_error (myError, OSD_WFile);
872 }
873 else if (dwDummy != 0) // end-of-file reached?
874 {
875 if (aPeekChar != '\n') // if we did not get a <CR><LF> sequence
876 {
877 // adjust file position
878 LARGE_INTEGER aDistanceToMove;
879 aDistanceToMove.QuadPart = -1;
880 SetFilePointerEx (myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
881 }
882 }
883 else
884 {
885 myIO |= FLAG_EOF;
886 }
887
888 theNbBytesRead = aNbBytesRead;
889 }
890 else if (aSeekPos != 0)
891 {
892 LARGE_INTEGER aDistanceToMove;
893 aDistanceToMove.QuadPart = aSeekPos;
894 SetFilePointerEx (myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
895 }
896 }
897 }
898 else if (myIO & FLAG_SOCKET
899 || myIO & FLAG_PIPE
900 || myIO & FLAG_NAMED_PIPE)
901 {
902 #ifndef OCCT_UWP
903 aNbBytesRead = (DWORD )OSD_File_getBuffer (myFileHandle, &aBuffer.ChangeFirst(), (DWORD )theNbBytes, TRUE, myIO & FLAG_SOCKET);
904 if ((int )aNbBytesRead == -1)
905 {
906 _osd_wnt_set_error (myError, OSD_WFile);
907 theBuffer.Clear();
908 theNbBytesRead = 0;
909 }
910 else if (aNbBytesRead == 0) // connection closed - set end-of-file flag
911 {
912 theBuffer.Clear();
913 theNbBytesRead = 0;
914 myIO |= FLAG_EOF;
915 }
916 else
917 {
918 theNbBytesRead = OSD_File_getLine (&aBuffer.ChangeFirst(), aNbBytesRead, aSeekPos);
919 if (theNbBytesRead == -1) // last character in the buffer is <CR> - peek next character to see if it is a <LF>
920 {
921 theNbBytesRead = aNbBytesRead; // (LD) always fits this case
922
923 const DWORD dwDummy = OSD_File_getBuffer (myFileHandle, &aPeekChar, 1, TRUE, myIO & FLAG_SOCKET);
924 if ((int )dwDummy == -1)
925 {
926 _osd_wnt_set_error (myError, OSD_WFile);
927 }
928 else if (dwDummy != 0) // connection closed?
929 {
930 if (aPeekChar == '\n') // we got a <CR><LF> sequence
931 {
932 ++aNbBytesRead; // (LD) we have to jump <LF>
933 }
934 }
935 else
936 {
937 myIO |= FLAG_EOF;
938 }
939 }
940 else if (aSeekPos != 0)
941 {
942 aNbBytesRead = aNbBytesRead + aSeekPos;
943 }
7fd59977 944
cda06ac0 945 // do not rewrite data in aBuffer
946 NCollection_Array1<char> aBuffer2 (0, theNbBytes + 2);
947 // remove pending input
948 OSD_File_getBuffer (myFileHandle, &aBuffer2.ChangeFirst(), aNbBytesRead, FALSE, myIO & FLAG_SOCKET);
949 }
950 #endif
951 }
952 else
953 {
954 throw Standard_ProgramError ("OSD_File::ReadLine(): incorrect call - file is a directory");
955 }
7fd59977 956
cda06ac0 957 if (!Failed() && !IsAtEnd())
958 {
959 theBuffer = &aBuffer.First();
960 }
7fd59977 961#else
cda06ac0 962 NCollection_Array1<char> aBuffer (0, theNbBytes);
963 char* aBufferGets = fgets (&aBuffer.ChangeFirst(), theNbBytes, (FILE* )myFILE);
964 if (aBufferGets == NULL)
965 {
966 if (!feof ((FILE* )myFILE))
967 {
968 myError.SetValue (errno, Iam, "ReadLine");
969 return;
970 }
7fd59977 971
cda06ac0 972 myIO = EOF;
973 theBuffer.Clear();
974 theNbBytesRead = 0;
975 }
976 else
977 {
978 aBuffer.ChangeLast() = '\0';
979 theNbBytesRead = (Standard_Integer )strlen (aBufferGets);
980 theBuffer.SetValue (1, aBufferGets);
981 theBuffer.Trunc (theNbBytesRead);
982 }
983#endif
7fd59977 984}
985
cda06ac0 986// =======================================================================
987// function : KindOfFile
988// purpose :
989// =======================================================================
990OSD_KindFile OSD_File::KindOfFile() const
991{
992 TCollection_AsciiString aFullName;
993 myPath.SystemName (aFullName);
994#ifdef _WIN32
995 Standard_Integer aFlags = myIO;
996 if (myFileHandle == INVALID_HANDLE_VALUE)
997 {
998 if (aFullName.IsEmpty())
999 {
1000 throw Standard_ProgramError ("OSD_File::KindOfFile(): incorrect call - no filename given");
1001 }
1002 aFlags = _get_file_type (aFullName.ToCString(), INVALID_HANDLE_VALUE);
1003 }
7fd59977 1004
cda06ac0 1005 switch (aFlags & FLAG_TYPE)
1006 {
1007 case FLAG_FILE: return OSD_FILE;
1008 case FLAG_DIRECTORY: return OSD_DIRECTORY;
1009 case FLAG_SOCKET: return OSD_SOCKET;
1010 }
1011 return OSD_UNKNOWN;
7fd59977 1012#else
cda06ac0 1013 struct stat aStatBuffer;
1014 if (stat (aFullName.ToCString(), &aStatBuffer) == 0)
1015 {
1016 if (S_ISDIR (aStatBuffer.st_mode)) { return OSD_DIRECTORY; }
1017 else if (S_ISREG (aStatBuffer.st_mode)) { return OSD_FILE; }
1018 else if (S_ISLNK (aStatBuffer.st_mode)) { return OSD_LINK; }
1019 else if (S_ISSOCK(aStatBuffer.st_mode)) { return OSD_SOCKET; }
1020 }
1021 return OSD_UNKNOWN;
7fd59977 1022#endif
7fd59977 1023}
1024
cda06ac0 1025// =======================================================================
1026// function : Read
1027// purpose :
1028// =======================================================================
1029void OSD_File::Read (const Standard_Address theBuffer,
1030 const Standard_Integer theNbBytes,
1031 Standard_Integer& theNbReadBytes)
7fd59977 1032{
cda06ac0 1033 if (OSD_File::KindOfFile ( ) == OSD_DIRECTORY)
1034 {
1035 throw Standard_ProgramError ("OSD_File::Read(): it is a directory");
1036 }
1037 if (!IsOpen())
1038 {
1039 throw Standard_ProgramError ("OSD_File::Read(): file is not open");
1040 }
1041 if (Failed())
1042 {
1043 Perror();
1044 }
1045 if (myMode == OSD_WriteOnly)
1046 {
1047 throw Standard_ProgramError ("OSD_File::Read(): file is Write only");
1048 }
1049 if (theNbBytes <= 0)
1050 {
1051 throw Standard_ProgramError ("OSD_File::Read(): theNbBytes is 0");
1052 }
1053 if (theBuffer == NULL)
1054 {
1055 throw Standard_ProgramError ("OSD_File::Read(): theBuffer is NULL");
1056 }
1057#ifdef _WIN32
1058 if (myIO & FLAG_PIPE && !(myIO & FLAG_READ_PIPE))
1059 {
1060 throw Standard_ProgramError ("OSD_File::Read(): attempt to read from write only pipe");
1061 }
7fd59977 1062
cda06ac0 1063 DWORD aNbReadBytes = 0;
1064 if (!ReadFile (myFileHandle, theBuffer, (DWORD )theNbBytes, &aNbReadBytes, NULL))
1065 {
1066 _osd_wnt_set_error (myError, OSD_WFile);
1067 aNbReadBytes = 0;
1068 }
1069 else if (aNbReadBytes == 0)
1070 {
1071 myIO |= FLAG_EOF;
1072 }
7fd59977 1073 else
cda06ac0 1074 {
1075 myIO &= ~FLAG_EOF;
1076 }
7fd59977 1077
cda06ac0 1078 theNbReadBytes = (Standard_Integer )aNbReadBytes;
1079#else
1080 theNbReadBytes = 0;
1081 int aNbReadBytes = read (myFileChannel, (char* )theBuffer, theNbBytes);
1082 if (aNbReadBytes == -1)
1083 {
1084 myError.SetValue (errno, Iam, "Read");
1085 }
7fd59977 1086 else
cda06ac0 1087 {
1088 if (aNbReadBytes < theNbBytes)
1089 {
1090 myIO = EOF;
1091 }
1092 theNbReadBytes = aNbReadBytes;
1093 }
1094#endif
7fd59977 1095}
1096
cda06ac0 1097// =======================================================================
1098// function : Write
1099// purpose :
1100// =======================================================================
1101void OSD_File::Write (const Standard_Address theBuffer,
1102 const Standard_Integer theNbBytes)
7fd59977 1103{
cda06ac0 1104 if (!IsOpen())
1105 {
1106 throw Standard_ProgramError ("OSD_File::Write(): file is not open");
1107 }
1108 if (Failed())
1109 {
1110 Perror();
1111 }
1112 if (myMode == OSD_ReadOnly)
1113 {
1114 throw Standard_ProgramError ("OSD_File::Write(): file is Read only");
1115 }
1116 if (theNbBytes <= 0)
1117 {
1118 throw Standard_ProgramError ("OSD_File::Write(): theNbBytes is null");
1119 }
1120#ifdef _WIN32
1121 if ((myIO & FLAG_PIPE) != 0
1122 && (myIO & FLAG_READ_PIPE) != 0)
1123 {
1124 throw Standard_ProgramError ("OSD_File::Write(): attempt to write to read only pipe");
1125 }
7fd59977 1126
cda06ac0 1127 DWORD aNbWritten = 0;
1128 if (!WriteFile (myFileHandle, theBuffer, (DWORD )theNbBytes, &aNbWritten, NULL)
1129 || aNbWritten != (DWORD )theNbBytes)
1130 {
1131 _osd_wnt_set_error (myError, OSD_WFile);
1132 }
1133#else
1134 const int aNbWritten = write (myFileChannel, (const char* )theBuffer, theNbBytes);
1135 if (aNbWritten == -1)
1136 {
1137 myError.SetValue (errno, Iam, "Write");
1138 }
1139 else if (aNbWritten < theNbBytes)
1140 {
1141 myIO = EOF;
1142 }
742cc8b0 1143#endif
cda06ac0 1144}
7fd59977 1145
cda06ac0 1146// =======================================================================
1147// function : Seek
1148// purpose :
1149// =======================================================================
1150void OSD_File::Seek (const Standard_Integer theOffset,
1151 const OSD_FromWhere theWhence)
6ff736d8 1152{
cda06ac0 1153 if (!IsOpen())
95e05159 1154 {
cda06ac0 1155 throw Standard_ProgramError ("OSD_File::Seek(): file is not open");
1156 }
1157 if (Failed())
1158 {
1159 Perror();
95e05159 1160 }
1161
cda06ac0 1162#ifdef _WIN32
1163 DWORD aWhere = 0;
1164 if (myIO & FLAG_FILE
1165 || myIO & FLAG_DIRECTORY)
1166 {
1167 switch (theWhence)
1168 {
1169 case OSD_FromBeginning: aWhere = FILE_BEGIN; break;
1170 case OSD_FromHere: aWhere = FILE_CURRENT; break;
1171 case OSD_FromEnd: aWhere = FILE_END; break;
1172 default:
1173 throw Standard_ProgramError ("OSD_File::Seek(): invalid parameter");
1174 }
95e05159 1175
cda06ac0 1176 LARGE_INTEGER aDistanceToMove, aNewFilePointer;
1177 aNewFilePointer.QuadPart = 0;
1178 aDistanceToMove.QuadPart = theOffset;
1179 if (!SetFilePointerEx (myFileHandle, aDistanceToMove, &aNewFilePointer, aWhere))
1180 {
1181 _osd_wnt_set_error (myError, OSD_WFile);
1182 }
1183 }
1184 myIO &= ~FLAG_EOF;
1185#else
1186 int aWhere = 0;
1187 switch (theWhence)
1188 {
1189 case OSD_FromBeginning: aWhere = SEEK_SET; break;
1190 case OSD_FromHere: aWhere = SEEK_CUR; break;
1191 case OSD_FromEnd: aWhere = SEEK_END; break;
1192 default:
1193 throw Standard_ProgramError ("OSD_File::Seek(): invalid parameter");
1194 }
95e05159 1195
cda06ac0 1196 off_t aStatus = lseek (myFileChannel, theOffset, aWhere);
1197 if (aStatus == -1)
1198 {
1199 myError.SetValue (errno, Iam, "Seek");
1200 }
1201#endif
95e05159 1202}
1203
cda06ac0 1204// =======================================================================
1205// function : Close
1206// purpose :
1207// =======================================================================
1208void OSD_File::Close()
1209{
1210 if (!IsOpen())
1211 {
1212 throw Standard_ProgramError ("OSD_File::Close(): file is not open");
1213 }
1214 if (Failed())
1215 {
1216 Perror();
1217 }
1218#ifdef _WIN32
1219 CloseHandle (myFileHandle);
1220 myFileHandle = INVALID_HANDLE_VALUE;
742cc8b0 1221#else
cda06ac0 1222 // note: it probably should be single call to fclose()...
1223 int status = close (myFileChannel);
1224 if (status == -1)
68299304 1225 {
cda06ac0 1226 myError.SetValue (errno, Iam, "Close");
68299304 1227 }
cda06ac0 1228 myFileChannel = -1;
1229 if (myFILE != NULL)
d9ff84e8 1230 {
cda06ac0 1231 status = fclose ((FILE* )myFILE);
1232 myFILE = NULL;
d9ff84e8 1233 }
cda06ac0 1234#endif
1235 myIO = 0;
1236}
7fd59977 1237
cda06ac0 1238// =======================================================================
1239// function : IsAtEnd
1240// purpose :
1241// =======================================================================
1242Standard_Boolean OSD_File::IsAtEnd()
1243{
1244 if (!IsOpen())
1245 {
1246 throw Standard_ProgramError ("OSD_File::IsAtEnd(): file is not open");
1247 }
7fd59977 1248
cda06ac0 1249#ifdef _WIN32
1250 return (myIO & FLAG_EOF) != 0;
1251#else
1252 return myIO == EOF;
1253#endif
1254}
7fd59977 1255
cda06ac0 1256// =======================================================================
1257// function : Link
1258// purpose :
1259// =======================================================================
1260/*void OSD_File::Link (const TCollection_AsciiString& theToFile)
1261{
1262 if (!IsOpen())
1263 {
1264 throw Standard_ProgramError ("OSD_File::Link(): file is not open");
1265 }
7fd59977 1266
cda06ac0 1267 TCollection_AsciiString aFilePath;
1268 myPath.SystemName (aFilePath);
1269 link (aFilePath.ToCString(), theToFile.ToCString());
1270}*/
7fd59977 1271
cda06ac0 1272#if defined(__CYGWIN32__) || defined(__MINGW32__)
1273 #ifdef __try /* is defined on MinGw as either "try" or "if (true)" */
1274 #undef __try
1275 #endif
1276 #define __try
1277 #define __finally
1278 #define __leave return
1279#endif
7fd59977 1280
cda06ac0 1281// =======================================================================
1282// function : SetLock
1283// purpose :
1284// =======================================================================
1285void OSD_File::SetLock (const OSD_LockType theLock)
1286{
1287 if (!IsOpen())
1288 {
1289 throw Standard_ProgramError("OSD_File::SetLock(): file is not open");
1290 }
1291#ifdef _WIN32
1292 DWORD dwFlags = 0;
1293 myLock = theLock;
1294 if (theLock == OSD_NoLock)
1295 {
1296 UnLock();
1297 return;
1298 }
1299 else if (theLock == OSD_ReadLock
1300 || theLock == OSD_ExclusiveLock)
1301 {
1302 dwFlags = LOCKFILE_EXCLUSIVE_LOCK;
1303 }
7fd59977 1304
cda06ac0 1305 OVERLAPPED anOverlapped;
1306 ZeroMemory (&anOverlapped, sizeof(OVERLAPPED));
1307 __try
1308 {
1309 LARGE_INTEGER aSize;
1310 aSize.QuadPart = Size();
1311 if (!LockFileEx (myFileHandle, dwFlags, 0, aSize.LowPart, aSize.HighPart, &anOverlapped))
1312 {
1313 _osd_wnt_set_error (myError, OSD_WFile);
1314 __leave;
1315 }
1316 ImperativeFlag = Standard_True;
1317 }
1318 __finally {}
7fd59977 1319
cda06ac0 1320#elif defined(POSIX)
1321 int aLock = 0;
1322 switch (theLock)
1323 {
1324 case OSD_ExclusiveLock:
1325 case OSD_WriteLock:
1326 aLock = F_LOCK;
1327 break;
1328 case OSD_ReadLock:
1329 return;
1330 default:
1331 myError.SetValue (EINVAL, Iam, "SetLock");
1332 return;
1333 }
7fd59977 1334
cda06ac0 1335 struct stat aStatBuf;
1336 if (fstat (myFileChannel, &aStatBuf) == -1)
1337 {
1338 myError.SetValue (errno, Iam, "SetLock");
1339 return;
1340 }
7fd59977 1341
cda06ac0 1342 const int aStatus = lockf (myFileChannel, aLock, aStatBuf.st_size);
1343 if (aStatus == -1)
1344 {
1345 myError.SetValue (errno, Iam, "SetLock");
1346 }
1347 else
1348 {
1349 myLock = theLock;
1350 }
1351#elif defined(SYSV)
1352 struct flock aLockKey;
1353 aLockKey.l_whence = 0;
1354 aLockKey.l_start = 0;
1355 aLockKey.l_len = 0;
1356 switch (theLock)
1357 {
1358 case OSD_ExclusiveLock:
1359 case OSD_WriteLock:
1360 aLockKey.l_type = F_WRLCK;
1361 break;
1362 case OSD_ReadLock:
1363 aLockKey.l_type = F_RDLCK;
1364 break;
1365 case OSD_NoLock:
1366 return;
1367 //default: myError.SetValue (EINVAL, Iam, "SetLock");
1368 }
7fd59977 1369
cda06ac0 1370 const int aStatus = fcntl (myFileChannel, F_SETLKW, &aLockKey);
1371 if (aStatus == -1)
1372 {
1373 myError.SetValue (errno, Iam, "SetLock");
1374 }
1375 else
1376 {
1377 myLock = theLock;
1378 }
7fd59977 1379
cda06ac0 1380 if (theLock == OSD_ExclusiveLock)
1381 {
1382 struct stat aStatBuf;
1383 fstat (myFileChannel, &aStatBuf);
1384 TCollection_AsciiString aFilePath;
1385 myPath.SystemName (aFilePath);
1386 chmod (aFilePath.ToCString(), aStatBuf.st_mode | S_ISGID);
1387 ImperativeFlag = Standard_True;
1388 }
1389#else /* BSD */
1390 int aLock = 0;
1391 switch (theLock)
1392 {
1393 case OSD_ExclusiveLock:
1394 case OSD_WriteLock:
1395 aLock = F_WRLCK;
1396 break;
1397 case OSD_ReadLock:
1398 aLock = F_RDLCK;
1399 break;
1400 default:
1401 myError.SetValue (EINVAL, Iam, "SetLock");
1402 return;
1403 }
7fd59977 1404
cda06ac0 1405 const int aStatus = flock (myFileChannel, aLock);
1406 if (aStatus == -1)
1407 {
1408 myError.SetValue (errno, Iam, "SetLock");
1409 }
1410 else
1411 {
1412 myLock = theLock;
1413 }
1414#endif
1415}
7fd59977 1416
cda06ac0 1417#if defined(__CYGWIN32__) || defined(__MINGW32__)
1418 #undef __try
1419 #undef __finally
1420 #undef __leave
1421#endif
7fd59977 1422
cda06ac0 1423// =======================================================================
1424// function : UnLock
1425// purpose :
1426// =======================================================================
1427void OSD_File::UnLock()
1428{
1429 if (!IsOpen())
1430 {
1431 throw Standard_ProgramError ("OSD_File::UnLock(): file is not open");
1432 }
1433#ifdef _WIN32
1434 if (ImperativeFlag)
1435 {
1436 LARGE_INTEGER aSize;
1437 aSize.QuadPart = Size();
1438
1439 OVERLAPPED anOverlappedArea;
1440 anOverlappedArea.Offset = 0;
1441 anOverlappedArea.OffsetHigh = 0;
1442 if (!UnlockFileEx (myFileHandle, 0, aSize.LowPart, aSize.HighPart, &anOverlappedArea))
1443 {
1444 _osd_wnt_set_error (myError, OSD_WFile);
1445 }
1446 ImperativeFlag = Standard_False;
1447 }
1448#elif defined(POSIX)
1449 struct stat aStatBuf;
1450 if (fstat (myFileChannel, &aStatBuf) == -1)
1451 {
1452 myError.SetValue (errno, Iam, "UnsetLock");
1453 return;
1454 }
7fd59977 1455
cda06ac0 1456 const int aStatus = lockf (myFileChannel, F_ULOCK, aStatBuf.st_size);
1457 if (aStatus == -1)
1458 {
1459 myError.SetValue (errno, Iam, "SetLock");
1460 }
1461 else
1462 {
1463 myLock = OSD_NoLock;
1464 }
1465#elif defined(SYSV)
1466 if (ImperativeFlag)
1467 {
1468 struct stat aStatBuf;
1469 fstat (myFileChannel, &aStatBuf);
1470 TCollection_AsciiString aBuffer;
1471 myPath.SystemName (aBuffer);
1472 chmod (aBuffer.ToCString(), aStatBuf.st_mode & ~S_ISGID);
1473 ImperativeFlag = Standard_False;
1474 }
7fd59977 1475
cda06ac0 1476 struct flock aLockKey;
1477 aLockKey.l_type = F_UNLCK;
1478 const int aStatus = fcntl (myFileChannel, F_SETLK, &aLockKey);
1479 if (aStatus == -1)
1480 {
1481 myError.SetValue (errno, Iam, "UnSetLock");
1482 }
1483 else
1484 {
1485 myLock = OSD_NoLock;
1486 }
1487#else
1488 const int aStatus = flock (myFileChannel, LOCK_UN);
1489 if (aStatus == -1)
1490 {
1491 myError.SetValue (errno, Iam, "UnSetLock");
1492 }
1493 else
1494 {
1495 myLock = OSD_NoLock;
1496 }
1497#endif
1498}
7fd59977 1499
cda06ac0 1500// =======================================================================
1501// function : Size
1502// purpose :
1503// =======================================================================
1504Standard_Size OSD_File::Size()
1505{
1506#ifdef _WIN32
1507 if (!IsOpen())
1508 {
1509 throw Standard_ProgramError ("OSD_File::Size(): file is not open");
1510 }
1511#if (_WIN32_WINNT >= 0x0500)
1512 LARGE_INTEGER aSize;
1513 aSize.QuadPart = 0;
1514 if (GetFileSizeEx (myFileHandle, &aSize) == 0)
1515 {
1516 _osd_wnt_set_error (myError, OSD_WFile);
1517 }
1518 return (Standard_Size )aSize.QuadPart;
1519#else
1520 DWORD aSize = GetFileSize (myFileHandle, NULL);
1521 if (aSize == INVALID_FILE_SIZE)
1522 {
1523 _osd_wnt_set_error (myError, OSD_WFile);
1524 }
1525 return aSize;
1526#endif
1527#else
1528 if (myPath.Name().Length() == 0)
1529 {
1530 throw Standard_ProgramError ("OSD_File::Size(): empty file name");
1531 }
7fd59977 1532
cda06ac0 1533 TCollection_AsciiString aFilePath;
1534 myPath.SystemName (aFilePath);
7fd59977 1535
cda06ac0 1536 struct stat aStatBuf;
1537 const int aStatus = stat (aFilePath.ToCString(), &aStatBuf);
1538 if (aStatus == -1)
1539 {
1540 myError.SetValue (errno, Iam, "Size");
1541 return 0;
1542 }
1543 return (Standard_Size )aStatBuf.st_size;
1544#endif
1545}
7fd59977 1546
cda06ac0 1547// =======================================================================
1548// function : IsOpen
1549// purpose :
1550// =======================================================================
1551Standard_Boolean OSD_File::IsOpen() const
1552{
1553#ifdef _WIN32
1554 return myFileHandle != INVALID_HANDLE_VALUE;
1555#else
1556 return myFileChannel != -1;
1557#endif
1558}
7fd59977 1559
cda06ac0 1560// =======================================================================
1561// function : IsReadable
1562// purpose :
1563// =======================================================================
1564Standard_Boolean OSD_File::IsReadable()
1565{
1566 TCollection_AsciiString aFileName;
1567 myPath.SystemName (aFileName);
1568#ifdef _WIN32
1569 HANDLE aChannel = OSD_File_openFile (aFileName, OSD_ReadOnly, OPEN_OLD);
1570 if (aChannel == INVALID_HANDLE_VALUE)
1571 {
1572 return Standard_False;
1573 }
7fd59977 1574
cda06ac0 1575 CloseHandle (aChannel);
1576 return Standard_True;
1577#else
1578 return access (aFileName.ToCString(), F_OK | R_OK) == 0;
1579#endif
1580}
7fd59977 1581
cda06ac0 1582// =======================================================================
1583// function : IsWriteable
1584// purpose :
1585// =======================================================================
1586Standard_Boolean OSD_File::IsWriteable()
1587{
1588 TCollection_AsciiString aFileName;
1589 myPath.SystemName (aFileName);
1590#ifdef _WIN32
1591 HANDLE aChannel = OSD_File_openFile (aFileName, OSD_ReadWrite, OPEN_OLD);
1592 if (aChannel == INVALID_HANDLE_VALUE)
1593 {
1594 return Standard_False;
1595 }
7fd59977 1596
cda06ac0 1597 CloseHandle (aChannel);
1598 return Standard_True;
1599#else
1600 return access (aFileName.ToCString(), F_OK | R_OK | W_OK) == 0;
1601#endif
1602}
7fd59977 1603
cda06ac0 1604// =======================================================================
1605// function : IsExecutable
1606// purpose :
1607// =======================================================================
1608Standard_Boolean OSD_File::IsExecutable()
1609{
1610#ifdef _WIN32
1611 return IsReadable();
1612#else
1613 TCollection_AsciiString aFileName;
1614 myPath.SystemName (aFileName);
1615 return access (aFileName.ToCString(), F_OK | X_OK) == 0;
1616#endif
1617}
7fd59977 1618
cda06ac0 1619// =======================================================================
1620// function : Capture
1621// purpose :
1622// =======================================================================
1623int OSD_File::Capture (int theDescr)
1624{
1625#ifdef _WIN32
1626 // Get POSIX file descriptor from this file handle
1627 int dFile = _open_osfhandle (reinterpret_cast<intptr_t>(myFileHandle), myMode);
1628 if (0 > dFile)
1629 {
1630 _osd_wnt_set_error (myError, OSD_WFile, myFileHandle);
1631 return -1;
1632 }
7fd59977 1633
cda06ac0 1634 // Duplicate an old file descriptor of the given one to be able to restore output to it later.
1635 int oldDescr = _dup (theDescr);
1636 // Redirect the output to this file
1637 _dup2 (dFile, theDescr);
7fd59977 1638
cda06ac0 1639 // Return the old descriptor
1640 return oldDescr;
1641#else
1642 // Duplicate an old file descriptor of the given one to be able to restore output to it later.
1643 int oldDescr = dup (theDescr);
1644 // Redirect the output to this file
1645 dup2 (myFileChannel, theDescr);
7fd59977 1646
cda06ac0 1647 // Return the old descriptor
1648 return oldDescr;
742cc8b0 1649#endif
cda06ac0 1650}
7fd59977 1651
cda06ac0 1652// =======================================================================
1653// function : Rewind
1654// purpose :
1655// =======================================================================
1656void OSD_File::Rewind()
7fd59977 1657{
cda06ac0 1658#ifdef _WIN32
1659 LARGE_INTEGER aDistanceToMove;
1660 aDistanceToMove.QuadPart = 0;
1661 SetFilePointerEx (myFileHandle, aDistanceToMove, NULL, FILE_BEGIN);
1662#else
1663 rewind ((FILE* )myFILE);
1664#endif
7fd59977 1665}
1666
cda06ac0 1667// =======================================================================
1668// function : ReadLastLine
1669// purpose :
1670// =======================================================================
1671Standard_Boolean OSD_File::ReadLastLine (TCollection_AsciiString& theLine,
1672 const Standard_Integer theDelay,
1673 const Standard_Integer theNbTries)
7fd59977 1674{
cda06ac0 1675 if (theNbTries <= 0)
1676 {
1677 return Standard_False;
1678 }
7fd59977 1679
cda06ac0 1680 const Standard_Integer TheMaxLength = 1000;
1681 for (Standard_Integer Count = theNbTries; Count > 0; --Count)
1682 {
1683 Standard_Integer aLen = 0;
1684 ReadLine (theLine, TheMaxLength, aLen);
1685 if (!theLine.IsEmpty())
1686 {
1687 return Standard_True;
1688 }
1689 OSD::SecSleep (theDelay);
7fd59977 1690 }
cda06ac0 1691 return Standard_False;
7fd59977 1692}
1693
cda06ac0 1694// =======================================================================
1695// function : Edit
1696// purpose :
1697// =======================================================================
1698Standard_Boolean OSD_File::Edit()
7fd59977 1699{
cda06ac0 1700 std::cout << "Function OSD_File::Edit() not yet implemented.\n";
1701 return Standard_False;
7fd59977 1702}
1703
7fd59977 1704
cda06ac0 1705// None of the existing security APIs are supported in a UWP applications
1706#ifdef _WIN32
1707#ifndef OCCT_UWP
4485f3d0 1708
cda06ac0 1709#if defined(__CYGWIN32__) || defined(__MINGW32__)
1710 #define __try
1711 #define __finally
1712 #define __leave return retVal
1713#endif
1714
1715PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd (const OSD_Protection& theProtection, BOOL theIsDir, const wchar_t* theFileName)
4485f3d0 1716{
cda06ac0 1717 BOOL fOK = FALSE;
1718 PACL pACL = NULL;
1719 HANDLE hProcess = NULL;
1720 PSID pSIDowner;
1721 DWORD dwACLsize = sizeof(ACL);
1722 DWORD dwIndex = 0;
1723 PTOKEN_OWNER pTkOwner = NULL;
1724 PTOKEN_GROUPS pTkGroups = NULL;
1725 PTOKEN_PRIMARY_GROUP pTkPrimaryGroup = NULL;
1726 PSECURITY_DESCRIPTOR retVal = NULL;
1727 PSECURITY_DESCRIPTOR pfSD = NULL;
1728 BOOL fDummy;
1729 PFILE_ACE pFileACE;
1730
1731 __try
4485f3d0 1732 {
cda06ac0 1733 const int j = theIsDir ? 1 : 0;
1734 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &hProcess))
1735 {
1736 __leave;
1737 }
1738 if ((pTkGroups = (PTOKEN_GROUPS )GetTokenInformationEx (hProcess, TokenGroups)) == NULL)
1739 {
1740 __leave;
1741 }
1742 if ((pTkOwner = (PTOKEN_OWNER )GetTokenInformationEx (hProcess, TokenOwner)) == NULL)
1743 {
1744 __leave;
1745 }
1746 if ((pTkPrimaryGroup = (PTOKEN_PRIMARY_GROUP )GetTokenInformationEx (hProcess, TokenPrimaryGroup)) == NULL)
1747 {
1748 __leave;
1749 }
7fd59977 1750
cda06ac0 1751retry:
1752 if (theFileName == NULL)
1753 {
1754 pSIDowner = pTkOwner->Owner;
1755 }
1756 else
1757 {
1758 pfSD = GetFileSecurityEx (theFileName, OWNER_SECURITY_INFORMATION);
1759 if (pfSD == NULL || !GetSecurityDescriptorOwner (pfSD, &pSIDowner, &fDummy))
1760 {
1761 theFileName = NULL;
1762 goto retry;
1763 }
1764 }
7fd59977 1765
cda06ac0 1766 PSID pSIDadmin = AdminSid();
1767 PSID pSIDworld = WorldSid();
1768
1769 DWORD dwAccessAdmin = OSD_File_getAccessMask (theProtection.System());
1770 DWORD dwAccessGroup = OSD_File_getAccessMask (theProtection.Group());
1771 DWORD dwAccessOwner = OSD_File_getAccessMask (theProtection.User());
1772 DWORD dwAccessWorld = OSD_File_getAccessMask (theProtection.World());
1773
1774 DWORD dwAccessAdminDir = OSD_File_getDirAccessMask (theProtection.System());
1775 //DWORD dwAccessGroupDir = OSD_File_getDirAccessMask (theProtection.Group());
1776 DWORD dwAccessOwnerDir = OSD_File_getDirAccessMask (theProtection.User());
1777 //DWORD dwAccessWorldDir = OSD_File_getDirAccessMask (theProtection.World());
1778 if (dwAccessGroup != 0)
1779 {
1780 for (int aGroupIter = 0; aGroupIter < (int )pTkGroups->GroupCount; ++aGroupIter)
1781 {
1782 PSID pSIDtemp = pTkGroups->Groups[aGroupIter].Sid;
1783 if (!NtPredefinedSid (pSIDtemp)
1784 && !EqualSid (pSIDtemp, pSIDworld)
1785 && !EqualSid (pSIDtemp, pTkPrimaryGroup->PrimaryGroup)
1786 && IsValidSid (pSIDtemp))
1787 {
1788 dwACLsize += ((GetLengthSid (pSIDtemp) + ACE_HEADER_SIZE) << j);
1789 }
1790 }
1791 }
7fd59977 1792
cda06ac0 1793 dwACLsize += (((GetLengthSid (pSIDowner) + ACE_HEADER_SIZE) << j)
1794 + ((GetLengthSid (pSIDadmin) + ACE_HEADER_SIZE) << j)
1795 + ((GetLengthSid (pSIDworld) + ACE_HEADER_SIZE) << j));
1796 if ((pACL = CreateAcl (dwACLsize)) == NULL)
1797 {
1798 __leave;
1799 }
1800
1801 if (dwAccessAdmin != 0)
1802 {
1803 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessAdmin, 0, pSIDadmin)) != NULL)
1804 {
1805 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1806 if (theIsDir)
1807 {
1808 pFileACE->dwMask = dwAccessAdminDir;
1809 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1810 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1811 }
1812 FreeAce (pFileACE);
1813 }
1814 }
1815
1816 if (dwAccessOwner != 0)
1817 {
1818 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessOwner, 0, pSIDowner)) != NULL)
1819 {
1820 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1821 if (theIsDir)
1822 {
1823 pFileACE->dwMask = dwAccessOwnerDir;
1824 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1825 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1826 }
1827 FreeAce (pFileACE);
1828 }
1829 }
1830
1831 if (dwAccessWorld != 0)
1832 {
1833 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessWorld, 0, pSIDworld)) != NULL)
1834 {
1835 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1836 if (theIsDir)
1837 {
1838 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1839 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1840 }
1841 FreeAce (pFileACE);
1842 }
1843 }
1844
1845 if (dwAccessGroup != 0)
1846 {
1847 for (int aGroupIter = 0; aGroupIter < (int )pTkGroups->GroupCount; ++aGroupIter)
1848 {
1849 PSID pSIDtemp = pTkGroups->Groups[aGroupIter].Sid;
1850 if (!NtPredefinedSid(pSIDtemp)
1851 && !EqualSid (pSIDtemp, pSIDworld)
1852 && !EqualSid (pSIDtemp, pTkPrimaryGroup->PrimaryGroup)
1853 && IsValidSid (pSIDtemp))
1854 {
1855 if (dwAccessGroup != 0)
1856 {
1857 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessGroup, 0, pSIDtemp)) != NULL)
1858 {
1859 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1860 if (theIsDir)
1861 {
1862 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1863 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1864 }
1865 FreeAce (pFileACE);
1866 }
1867 }
1868 }
1869 }
1870 }
1871
1872 if ((retVal = AllocSD()) == NULL)
1873 {
1874 __leave;
1875 }
1876
1877 if (!SetSecurityDescriptorDacl (retVal, TRUE, pACL, TRUE))
1878 {
1879 __leave;
1880 }
1881 fOK = TRUE;
1882 } // end __try
1883
1884 __finally
1885 {
1886 if (!fOK)
1887 {
1888 if (retVal != NULL)
1889 {
1890 FreeSD (retVal);
1891 }
1892 else if (pACL != NULL)
1893 {
1894 FreeAcl (pACL);
1895 }
1896 retVal = NULL;
1897 }
1898
1899 if (hProcess != NULL)
1900 {
1901 CloseHandle (hProcess);
1902 }
1903 if (pTkOwner != NULL)
1904 {
1905 FreeTokenInformation (pTkOwner);
1906 }
1907 if (pTkGroups != NULL)
1908 {
1909 FreeTokenInformation (pTkGroups);
1910 }
1911 if (pTkPrimaryGroup != NULL)
1912 {
1913 FreeTokenInformation (pTkPrimaryGroup);
1914 }
1915 if (pfSD != NULL)
1916 {
1917 FreeFileSecurity (pfSD);
1918 }
7fd59977 1919 }
7fd59977 1920
cda06ac0 1921 return retVal;
1922}
7fd59977 1923
cda06ac0 1924BOOL __fastcall _osd_wnt_sd_to_protection (PSECURITY_DESCRIPTOR pSD, OSD_Protection& theProtection, BOOL theIsDir)
7fd59977 1925{
cda06ac0 1926 BOOL fPresent = FALSE;
1927 BOOL fDefaulted = FALSE;
1928 PACL pACL;
1929 PSID pSIDowner;
1930 BOOL retVal = FALSE;
1931 __try
1932 {
1933 if (!GetSecurityDescriptorOwner (pSD, &pSIDowner, &fDefaulted))
1934 {
1935 __leave;
1936 }
1937 if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pACL, &fDefaulted)
1938 || !fPresent)
1939 {
1940 __leave;
1941 }
1942 if (pSIDowner == NULL || pACL == NULL)
1943 {
1944 SetLastError (ERROR_NO_SECURITY_ON_OBJECT);
1945 __leave;
1946 }
1947
1948 PSID pSIDadmin = AdminSid();
1949 PSID pSIDworld = WorldSid();
1950 DWORD dwAccessOwner = 0;
1951 DWORD dwAccessGroup = 0;
1952 DWORD dwAccessAdmin = 0;
1953 DWORD dwAccessWorld = 0;
1954 for (DWORD anAceIter = 0; anAceIter < pACL->AceCount; ++anAceIter)
1955 {
1956 LPVOID pACE;
1957 if (GetAce (pACL, anAceIter, &pACE))
1958 {
1959 const DWORD dwAccess = ((PACE_HEADER )pACE)->AceType == ACCESS_DENIED_ACE_TYPE
1960 ? 0
1961 : *GET_MSK(pACE);
1962 if (EqualSid (pSIDowner, GET_SID(pACE)))
1963 {
1964 dwAccessOwner = dwAccess;
1965 }
1966 else if (EqualSid (pSIDadmin, GET_SID(pACE)))
1967 {
1968 dwAccessAdmin = dwAccess;
1969 }
1970 else if (EqualSid (pSIDworld, GET_SID(pACE)))
1971 {
1972 dwAccessWorld = dwAccess;
1973 }
1974 else
1975 {
1976 dwAccessGroup = dwAccess;
1977 }
1978 }
1979 }
7fd59977 1980
cda06ac0 1981 typedef OSD_SingleProtection (*OSD_File_getProtection_t)(DWORD );
1982 OSD_File_getProtection_t aGetProtFunc = theIsDir ? &OSD_File_getProtectionDir : &OSD_File_getProtection;
1983 theProtection.SetValues (aGetProtFunc (dwAccessAdmin),
1984 aGetProtFunc (dwAccessOwner),
1985 aGetProtFunc (dwAccessGroup),
1986 aGetProtFunc (dwAccessWorld));
1987 retVal = TRUE;
1988 } // end __try
1989 __finally {}
1990
1991 return retVal;
1992} // end _osd_wnt_sd_to_protection
7fd59977 1993
cda06ac0 1994#if defined(__CYGWIN32__) || defined(__MINGW32__)
1995 #undef __try
1996 #undef __finally
1997 #undef __leave
1998#endif
7fd59977 1999
cda06ac0 2000#endif
2001#endif /* _WIN32 */