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