1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
19 #include <OSD_File.hxx>
21 #include <NCollection_Array1.hxx>
23 #include <OSD_OSDError.hxx>
24 #include <OSD_Path.hxx>
25 #include <OSD_Protection.hxx>
26 #include <OSD_WhoAmI.hxx>
27 #include <Standard_ProgramError.hxx>
28 #include <TCollection_ExtendedString.hxx>
32 #include <OSD_WNT.hxx>
39 #define ACE_HEADER_SIZE (sizeof(ACCESS_ALLOWED_ACE) - sizeof (DWORD))
45 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
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);
51 static int OSD_File_getBuffer (HANDLE theChannel,
59 const int aFlags = theIsPeek ? MSG_PEEK : 0;
60 const int aRetVal = recv ((SOCKET )theChannel, theBuffer, (int )theSize, aFlags);
61 return aRetVal != SOCKET_ERROR
70 if (!PeekNamedPipe (theChannel, theBuffer, theSize, &aBytesRead, &aDummy, &aDummy)
71 && GetLastError() != ERROR_BROKEN_PIPE)
75 return (int )aBytesRead;
77 else if (!ReadFile (theChannel, theBuffer, theSize, &aBytesRead, NULL))
81 return (int )aBytesRead;
84 static OSD_SingleProtection OSD_File_getProtection (DWORD theMask)
88 case FILE_GENERIC_READ:
90 case FILE_GENERIC_WRITE:
92 case FILE_GENERIC_READ | FILE_GENERIC_WRITE:
94 case FILE_GENERIC_EXECUTE:
96 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE:
98 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
100 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE:
104 case FILE_GENERIC_READ | DELETE:
106 case FILE_GENERIC_WRITE | DELETE:
108 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE:
110 case FILE_GENERIC_EXECUTE | DELETE:
112 case FILE_GENERIC_READ | FILE_GENERIC_EXECUTE | DELETE:
114 case FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
116 case FILE_ALL_ACCESS:
117 case FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE:
123 static OSD_SingleProtection OSD_File_getProtectionDir (DWORD theMask)
131 case GENERIC_READ | GENERIC_WRITE:
133 case GENERIC_EXECUTE:
135 case GENERIC_READ | GENERIC_EXECUTE:
137 case GENERIC_WRITE | GENERIC_EXECUTE:
139 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE:
143 case GENERIC_READ | DELETE:
145 case GENERIC_WRITE | DELETE:
147 case GENERIC_READ | GENERIC_WRITE | DELETE:
149 case GENERIC_EXECUTE | DELETE:
151 case GENERIC_READ | GENERIC_EXECUTE | DELETE:
153 case GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
155 case FILE_ALL_ACCESS:
156 case GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE:
161 // remote directories (on Samba server) have flags like for files
162 return OSD_File_getProtection (theMask);
166 static DWORD OSD_File_getAccessMask (OSD_SingleProtection theProtection)
168 switch (theProtection)
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;
187 throw Standard_ProgramError ("OSD_File_getAccessMask(): incorrect parameter");
190 static DWORD OSD_File_getDirAccessMask (OSD_SingleProtection theProtection)
192 switch (theProtection)
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;
211 throw Standard_ProgramError ("OSD_File_getDirAccessMask(): incorrect parameter");
214 struct OSD_File_WntKey
217 const wchar_t* keyPath;
220 #endif /* ! OCCT_UWP */
222 Standard_Integer __fastcall _get_file_type (Standard_CString theFileName,
223 HANDLE theFileHandle)
225 const int aFileType = theFileHandle == INVALID_HANDLE_VALUE
227 : GetFileType (theFileHandle);
230 case FILE_TYPE_UNKNOWN:
234 const TCollection_ExtendedString aFileNameW (theFileName, Standard_True);
235 WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
236 if (GetFileAttributesExW (aFileNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
238 return aFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FLAG_DIRECTORY : FLAG_FILE;
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)
253 theBuffer[theBuffSize] = 0;
254 for (char* aCharIter = theBuffer; *aCharIter != 0; )
256 if (*aCharIter == '\n')
258 ++aCharIter; // jump newline char
260 theSeekPos = LONG(aCharIter - theBuffer - theBuffSize);
261 return Standard_Integer(aCharIter - theBuffer);
263 else if (aCharIter[0] == '\r'
264 && aCharIter[1] == '\n')
266 *(aCharIter++) = '\n'; // Substitute carriage return by newline
268 theSeekPos = LONG(aCharIter + 1 - theBuffer - theBuffSize);
269 return Standard_Integer(aCharIter - theBuffer);
271 else if (aCharIter[0] == '\r'
272 && aCharIter[1] == '\0')
274 *aCharIter = '\n' ; // Substitute carriage return by newline
284 static HANDLE OSD_File_openFile (const TCollection_AsciiString& theFileName,
285 OSD_OpenMode theOpenMode,
286 DWORD theOptions, bool* theIsNew = NULL)
288 DWORD dwDesiredAccess = 0;
292 dwDesiredAccess = GENERIC_READ;
295 dwDesiredAccess = GENERIC_WRITE;
298 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
301 throw Standard_ProgramError ("OSD_File_openFile(): incorrect parameter");
304 DWORD dwCreationDistribution = (theOptions != OPEN_NEW) ? OPEN_EXISTING : CREATE_ALWAYS;
305 const TCollection_ExtendedString aFileNameW (theFileName);
307 HANDLE aFileHandle = CreateFileW (aFileNameW.ToWideString(), dwDesiredAccess,
308 FILE_SHARE_READ | FILE_SHARE_WRITE,
309 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL);
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);
320 if (aFileHandle != INVALID_HANDLE_VALUE
321 || theOptions != OPEN_APPEND
322 || GetLastError() != ERROR_FILE_NOT_FOUND)
327 dwCreationDistribution = CREATE_ALWAYS;
329 aFileHandle = CreateFileW (aFileNameW.ToWideString(), dwDesiredAccess,
330 FILE_SHARE_READ | FILE_SHARE_WRITE,
331 NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL );
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 );
348 const OSD_WhoAmI Iam = OSD_WFile;
350 #if defined (sun) || defined(SOLARIS)
361 #include <sys/stat.h>
363 #define NEWLINE '\10';
366 // =======================================================================
367 // function : OSD_File
369 // =======================================================================
370 OSD_File::OSD_File() :
372 myFileHandle (INVALID_HANDLE_VALUE),
379 myMode (OSD_ReadWrite),
380 ImperativeFlag (Standard_False)
385 // =======================================================================
386 // function : OSD_File
388 // =======================================================================
389 OSD_File::OSD_File (const OSD_Path& theName)
390 : OSD_FileNode (theName),
392 myFileHandle (INVALID_HANDLE_VALUE),
399 myMode (OSD_ReadWrite),
400 ImperativeFlag (Standard_False)
405 // =======================================================================
406 // function : ~OSD_File
408 // =======================================================================
409 OSD_File::~OSD_File()
421 // =======================================================================
424 // =======================================================================
425 void OSD_File::Build (const OSD_OpenMode theMode,
426 const OSD_Protection& theProtect)
428 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
430 throw Standard_ProgramError ("OSD_File::Build(): it is a directory");
434 throw Standard_ProgramError ("OSD_File::Build(): incorrect call - file already opened");
437 TCollection_AsciiString aFileName;
438 myPath.SystemName (aFileName);
440 if (aFileName.IsEmpty())
442 throw Standard_ProgramError ("OSD_File::Build(): incorrect call - no filename given");
446 myFileHandle = OSD_File_openFile (aFileName, theMode, OPEN_NEW);
447 if (myFileHandle == INVALID_HANDLE_VALUE)
449 _osd_wnt_set_error (myError, OSD_WFile);
454 SetProtection (theProtect);
461 if (myPath.Name().Length() == 0)
463 throw Standard_ProgramError ("OSD_File::Build(): no name was given");
466 const char* anFDOpenMode = "r";
467 Standard_Integer anOpenMode = O_CREAT | O_TRUNC;
471 anOpenMode |= O_RDONLY;
475 anOpenMode |= O_WRONLY;
479 anOpenMode |= O_RDWR;
485 myFileChannel = open (aFileName.ToCString(), anOpenMode, theProtect.Internal());
486 if (myFileChannel >= 0)
488 myFILE = fdopen (myFileChannel, anFDOpenMode);
492 myError.SetValue (errno, Iam, "Open");
497 // =======================================================================
500 // =======================================================================
501 void OSD_File::Append (const OSD_OpenMode theMode,
502 const OSD_Protection& theProtect)
504 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
506 throw Standard_ProgramError ("OSD_File::Append(): it is a directory");
510 throw Standard_ProgramError ("OSD_File::Append(): incorrect call - file already opened");
513 TCollection_AsciiString aFileName;
514 myPath.SystemName (aFileName);
516 if (aFileName.IsEmpty())
518 throw Standard_ProgramError ("OSD_File::Append(): incorrect call - no filename given");
521 bool isNewFile = false;
523 myFileHandle = OSD_File_openFile (aFileName, theMode, OPEN_APPEND, &isNewFile);
524 if (myFileHandle == INVALID_HANDLE_VALUE)
526 _osd_wnt_set_error (myError, OSD_WFile);
532 myIO |= _get_file_type (aFileName.ToCString(), myFileHandle);
533 Seek (0, OSD_FromEnd);
538 SetProtection (theProtect);
546 if (myPath.Name().Length() == 0)
548 throw Standard_ProgramError ("OSD_File::Append(): no name was given");
551 const char* anFDOpenMode = "r";
552 Standard_Integer anOpenMode = O_APPEND;
556 anOpenMode |= O_RDONLY;
560 anOpenMode |= O_WRONLY;
564 anOpenMode |= O_RDWR;
571 // if file doesn't exist, creates it
572 anOpenMode |= O_CREAT;
576 myFileChannel = open (aFileName.ToCString(), anOpenMode, theProtect.Internal());
577 if (myFileChannel >= 0)
579 myFILE = fdopen (myFileChannel, anFDOpenMode);
583 myError.SetValue (errno, Iam, "Open");
588 // =======================================================================
591 // =======================================================================
592 void OSD_File::Open (const OSD_OpenMode theMode,
593 const OSD_Protection& theProtect)
595 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
597 throw Standard_ProgramError ("OSD_File::Open(): it is a directory");
601 throw Standard_ProgramError ("OSD_File::Open(): incorrect call - file already opened");
604 TCollection_AsciiString aFileName;
605 myPath.SystemName (aFileName);
607 if (aFileName.IsEmpty())
609 throw Standard_ProgramError ("OSD_File::Open(): incorrect call - no filename given");
614 myFileHandle = OSD_File_openFile (aFileName, theMode, OPEN_OLD);
615 if (myFileHandle == INVALID_HANDLE_VALUE)
617 _osd_wnt_set_error (myError, OSD_WFile);
621 myIO |= _get_file_type (aFileName.ToCString(), myFileHandle);
624 if (myPath.Name().Length() == 0)
626 throw Standard_ProgramError ("OSD_File::Open(): no name was given");
629 const char* anFDOpenMode = "r";
630 Standard_Integer anOpenMode = 0;
634 anOpenMode |= O_RDONLY;
638 anOpenMode |= O_WRONLY;
642 anOpenMode |= O_RDWR;
648 myFileChannel = open (aFileName.ToCString(), anOpenMode, theProtect.Internal());
649 if (myFileChannel >= 0)
651 myFILE = fdopen (myFileChannel, anFDOpenMode);
655 myError.SetValue (errno, Iam, "Open");
660 // =======================================================================
661 // function : BuildTemporary
663 // =======================================================================
664 void OSD_File::BuildTemporary()
668 TCollection_ExtendedString aTmpFolderW;
671 const OSD_File_WntKey TheRegKeys[2] =
673 { HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment" },
674 { HKEY_USERS, L".DEFAULT\\Environment" }
676 for (int aKeyIter = 0; aKeyIter < 2; ++aKeyIter)
679 if (RegOpenKeyExW (TheRegKeys[aKeyIter].hKey, TheRegKeys[aKeyIter].keyPath, 0, KEY_QUERY_VALUE, &aRegKey) != ERROR_SUCCESS)
684 DWORD aKeyType = 0, aKeySize = 0;
685 if (RegQueryValueExW (aRegKey, L"TEMP", NULL, &aKeyType, NULL, &aKeySize) == ERROR_SUCCESS)
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)
691 wchar_t aTmpBuffer[MAX_PATH];
692 ExpandEnvironmentStringsW (&aKeyValW.First(), aTmpBuffer, MAX_PATH);
693 aTmpFolderW = TCollection_ExtendedString (aTmpBuffer);
697 aTmpFolderW = TCollection_ExtendedString (&aKeyValW.First());
701 RegCloseKey (aRegKey);
705 // Windows Registry not supported by UWP
707 wchar_t aTmpBuffer[MAX_PATH];
708 fOK = GetTempPathW (_countof(aTmpBuffer), aTmpBuffer) != 0;
709 aTmpFolderW = TCollection_ExtendedString (aTmpBuffer);
717 wchar_t aTmpPathW[MAX_PATH];
718 GetTempFileNameW (aTmpFolderW.ToWideString(), L"CSF", 0, aTmpPathW);
724 SetPath (OSD_Path (TCollection_AsciiString (aTmpPathW)));
725 Build (OSD_ReadWrite, OSD_Protection());
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
740 char aTmpName[] = "/tmp/CSFXXXXXX";
741 myFileChannel = mkstemp (aTmpName);
742 const TCollection_AsciiString aName (aTmpName);
743 const OSD_Path aPath (aName);
745 myFILE = fdopen (myFileChannel, "w+");
747 myMode = OSD_ReadWrite;
752 // =======================================================================
755 // =======================================================================
756 void OSD_File::Read (TCollection_AsciiString& theBuffer,
757 const Standard_Integer theNbBytes)
759 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
761 throw Standard_ProgramError ("OSD_File::Read(): it is a directory");
765 throw Standard_ProgramError ("OSD_File::Read(): file is not open");
771 if (myMode == OSD_WriteOnly)
773 throw Standard_ProgramError ("OSD_File::Read(): file is Write only");
777 throw Standard_ProgramError ("OSD_File::Read(): theNbBytes is 0");
780 NCollection_Array1<char> aBuffer (0, theNbBytes);
781 Standard_Integer aNbBytesRead = 0;
783 Read (&aBuffer.ChangeFirst(), theNbBytes, aNbBytesRead);
785 aNbBytesRead = read (myFileChannel, &aBuffer.ChangeFirst(), theNbBytes);
786 if (aNbBytesRead == -1)
789 myError.SetValue (errno, Iam, "Read");
791 else if (aNbBytesRead < theNbBytes)
796 if (aNbBytesRead != 0)
798 aBuffer.ChangeValue (aNbBytesRead) = '\0';
799 theBuffer = &aBuffer.First();
807 // =======================================================================
808 // function : ReadLine
810 // =======================================================================
811 void OSD_File::ReadLine (TCollection_AsciiString& theBuffer,
812 const Standard_Integer theNbBytes,
813 Standard_Integer& theNbBytesRead)
815 if (OSD_File::KindOfFile() == OSD_DIRECTORY)
817 throw Standard_ProgramError ("OSD_File::ReadLine(): it is a directory");
821 throw Standard_ProgramError ("OSD_File::ReadLine(): file is not open");
827 if (myMode == OSD_WriteOnly)
829 throw Standard_ProgramError ("OSD_File::ReadLine(): file is Write only");
833 throw Standard_ProgramError ("OSD_File::ReadLine(): theNbBytes is 0");
836 if (myIO & FLAG_PIPE && !(myIO & FLAG_READ_PIPE))
838 throw Standard_ProgramError ("OSD_File::ReadLine(): attempt to read from write only pipe");
841 DWORD aNbBytesRead = 0;
843 char aPeekChar = '\0';
844 // +----> leave space for end-of-string
845 // | plus <CR><LF> sequence
847 NCollection_Array1<char> aBuffer (0, theNbBytes + 2);
848 if (myIO & FLAG_FILE)
850 if (!ReadFile (myFileHandle, &aBuffer.ChangeFirst(), theNbBytes, &aNbBytesRead, NULL))
852 _osd_wnt_set_error (myError, OSD_WFile);
856 else if (aNbBytesRead == 0)
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>
869 if (!ReadFile (myFileHandle, &aPeekChar, 1, &dwDummy, NULL))
871 _osd_wnt_set_error (myError, OSD_WFile);
873 else if (dwDummy != 0) // end-of-file reached?
875 if (aPeekChar != '\n') // if we did not get a <CR><LF> sequence
877 // adjust file position
878 LARGE_INTEGER aDistanceToMove;
879 aDistanceToMove.QuadPart = -1;
880 SetFilePointerEx (myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
888 theNbBytesRead = aNbBytesRead;
890 else if (aSeekPos != 0)
892 LARGE_INTEGER aDistanceToMove;
893 aDistanceToMove.QuadPart = aSeekPos;
894 SetFilePointerEx (myFileHandle, aDistanceToMove, NULL, FILE_CURRENT);
898 else if (myIO & FLAG_SOCKET
900 || myIO & FLAG_NAMED_PIPE)
903 aNbBytesRead = (DWORD )OSD_File_getBuffer (myFileHandle, &aBuffer.ChangeFirst(), (DWORD )theNbBytes, TRUE, myIO & FLAG_SOCKET);
904 if ((int )aNbBytesRead == -1)
906 _osd_wnt_set_error (myError, OSD_WFile);
910 else if (aNbBytesRead == 0) // connection closed - set end-of-file flag
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>
921 theNbBytesRead = aNbBytesRead; // (LD) always fits this case
923 const DWORD dwDummy = OSD_File_getBuffer (myFileHandle, &aPeekChar, 1, TRUE, myIO & FLAG_SOCKET);
924 if ((int )dwDummy == -1)
926 _osd_wnt_set_error (myError, OSD_WFile);
928 else if (dwDummy != 0) // connection closed?
930 if (aPeekChar == '\n') // we got a <CR><LF> sequence
932 ++aNbBytesRead; // (LD) we have to jump <LF>
940 else if (aSeekPos != 0)
942 aNbBytesRead = aNbBytesRead + aSeekPos;
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);
954 throw Standard_ProgramError ("OSD_File::ReadLine(): incorrect call - file is a directory");
957 if (!Failed() && !IsAtEnd())
959 theBuffer = &aBuffer.First();
962 NCollection_Array1<char> aBuffer (0, theNbBytes);
963 char* aBufferGets = fgets (&aBuffer.ChangeFirst(), theNbBytes, (FILE* )myFILE);
964 if (aBufferGets == NULL)
966 if (!feof ((FILE* )myFILE))
968 myError.SetValue (errno, Iam, "ReadLine");
978 aBuffer.ChangeLast() = '\0';
979 theNbBytesRead = (Standard_Integer )strlen (aBufferGets);
980 theBuffer.SetValue (1, aBufferGets);
981 theBuffer.Trunc (theNbBytesRead);
986 // =======================================================================
987 // function : KindOfFile
989 // =======================================================================
990 OSD_KindFile OSD_File::KindOfFile() const
992 TCollection_AsciiString aFullName;
993 myPath.SystemName (aFullName);
995 Standard_Integer aFlags = myIO;
996 if (myFileHandle == INVALID_HANDLE_VALUE)
998 if (aFullName.IsEmpty())
1000 throw Standard_ProgramError ("OSD_File::KindOfFile(): incorrect call - no filename given");
1002 aFlags = _get_file_type (aFullName.ToCString(), INVALID_HANDLE_VALUE);
1005 switch (aFlags & FLAG_TYPE)
1007 case FLAG_FILE: return OSD_FILE;
1008 case FLAG_DIRECTORY: return OSD_DIRECTORY;
1009 case FLAG_SOCKET: return OSD_SOCKET;
1013 struct stat aStatBuffer;
1014 if (stat (aFullName.ToCString(), &aStatBuffer) == 0)
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; }
1025 // =======================================================================
1028 // =======================================================================
1029 void OSD_File::Read (const Standard_Address theBuffer,
1030 const Standard_Integer theNbBytes,
1031 Standard_Integer& theNbReadBytes)
1033 if (OSD_File::KindOfFile ( ) == OSD_DIRECTORY)
1035 throw Standard_ProgramError ("OSD_File::Read(): it is a directory");
1039 throw Standard_ProgramError ("OSD_File::Read(): file is not open");
1045 if (myMode == OSD_WriteOnly)
1047 throw Standard_ProgramError ("OSD_File::Read(): file is Write only");
1049 if (theNbBytes <= 0)
1051 throw Standard_ProgramError ("OSD_File::Read(): theNbBytes is 0");
1053 if (theBuffer == NULL)
1055 throw Standard_ProgramError ("OSD_File::Read(): theBuffer is NULL");
1058 if (myIO & FLAG_PIPE && !(myIO & FLAG_READ_PIPE))
1060 throw Standard_ProgramError ("OSD_File::Read(): attempt to read from write only pipe");
1063 DWORD aNbReadBytes = 0;
1064 if (!ReadFile (myFileHandle, theBuffer, (DWORD )theNbBytes, &aNbReadBytes, NULL))
1066 _osd_wnt_set_error (myError, OSD_WFile);
1069 else if (aNbReadBytes == 0)
1078 theNbReadBytes = (Standard_Integer )aNbReadBytes;
1081 int aNbReadBytes = read (myFileChannel, (char* )theBuffer, theNbBytes);
1082 if (aNbReadBytes == -1)
1084 myError.SetValue (errno, Iam, "Read");
1088 if (aNbReadBytes < theNbBytes)
1092 theNbReadBytes = aNbReadBytes;
1097 // =======================================================================
1100 // =======================================================================
1101 void OSD_File::Write (const Standard_Address theBuffer,
1102 const Standard_Integer theNbBytes)
1106 throw Standard_ProgramError ("OSD_File::Write(): file is not open");
1112 if (myMode == OSD_ReadOnly)
1114 throw Standard_ProgramError ("OSD_File::Write(): file is Read only");
1116 if (theNbBytes <= 0)
1118 throw Standard_ProgramError ("OSD_File::Write(): theNbBytes is null");
1121 if ((myIO & FLAG_PIPE) != 0
1122 && (myIO & FLAG_READ_PIPE) != 0)
1124 throw Standard_ProgramError ("OSD_File::Write(): attempt to write to read only pipe");
1127 DWORD aNbWritten = 0;
1128 if (!WriteFile (myFileHandle, theBuffer, (DWORD )theNbBytes, &aNbWritten, NULL)
1129 || aNbWritten != (DWORD )theNbBytes)
1131 _osd_wnt_set_error (myError, OSD_WFile);
1134 const int aNbWritten = write (myFileChannel, (const char* )theBuffer, theNbBytes);
1135 if (aNbWritten == -1)
1137 myError.SetValue (errno, Iam, "Write");
1139 else if (aNbWritten < theNbBytes)
1146 // =======================================================================
1149 // =======================================================================
1150 void OSD_File::Seek (const Standard_Integer theOffset,
1151 const OSD_FromWhere theWhence)
1155 throw Standard_ProgramError ("OSD_File::Seek(): file is not open");
1164 if (myIO & FLAG_FILE
1165 || myIO & FLAG_DIRECTORY)
1169 case OSD_FromBeginning: aWhere = FILE_BEGIN; break;
1170 case OSD_FromHere: aWhere = FILE_CURRENT; break;
1171 case OSD_FromEnd: aWhere = FILE_END; break;
1173 throw Standard_ProgramError ("OSD_File::Seek(): invalid parameter");
1176 LARGE_INTEGER aDistanceToMove, aNewFilePointer;
1177 aNewFilePointer.QuadPart = 0;
1178 aDistanceToMove.QuadPart = theOffset;
1179 if (!SetFilePointerEx (myFileHandle, aDistanceToMove, &aNewFilePointer, aWhere))
1181 _osd_wnt_set_error (myError, OSD_WFile);
1189 case OSD_FromBeginning: aWhere = SEEK_SET; break;
1190 case OSD_FromHere: aWhere = SEEK_CUR; break;
1191 case OSD_FromEnd: aWhere = SEEK_END; break;
1193 throw Standard_ProgramError ("OSD_File::Seek(): invalid parameter");
1196 off_t aStatus = lseek (myFileChannel, theOffset, aWhere);
1199 myError.SetValue (errno, Iam, "Seek");
1204 // =======================================================================
1207 // =======================================================================
1208 void OSD_File::Close()
1212 throw Standard_ProgramError ("OSD_File::Close(): file is not open");
1219 CloseHandle (myFileHandle);
1220 myFileHandle = INVALID_HANDLE_VALUE;
1222 // note: it probably should be single call to fclose()...
1223 int status = close (myFileChannel);
1226 myError.SetValue (errno, Iam, "Close");
1231 status = fclose ((FILE* )myFILE);
1238 // =======================================================================
1239 // function : IsAtEnd
1241 // =======================================================================
1242 Standard_Boolean OSD_File::IsAtEnd()
1246 throw Standard_ProgramError ("OSD_File::IsAtEnd(): file is not open");
1250 return (myIO & FLAG_EOF) != 0;
1256 // =======================================================================
1259 // =======================================================================
1260 /*void OSD_File::Link (const TCollection_AsciiString& theToFile)
1264 throw Standard_ProgramError ("OSD_File::Link(): file is not open");
1267 TCollection_AsciiString aFilePath;
1268 myPath.SystemName (aFilePath);
1269 link (aFilePath.ToCString(), theToFile.ToCString());
1272 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1273 #ifdef __try /* is defined on MinGw as either "try" or "if (true)" */
1278 #define __leave return
1281 // =======================================================================
1282 // function : SetLock
1284 // =======================================================================
1285 void OSD_File::SetLock (const OSD_LockType theLock)
1289 throw Standard_ProgramError("OSD_File::SetLock(): file is not open");
1294 if (theLock == OSD_NoLock)
1299 else if (theLock == OSD_ReadLock
1300 || theLock == OSD_ExclusiveLock)
1302 dwFlags = LOCKFILE_EXCLUSIVE_LOCK;
1305 OVERLAPPED anOverlapped;
1306 ZeroMemory (&anOverlapped, sizeof(OVERLAPPED));
1309 LARGE_INTEGER aSize;
1310 aSize.QuadPart = Size();
1311 if (!LockFileEx (myFileHandle, dwFlags, 0, aSize.LowPart, aSize.HighPart, &anOverlapped))
1313 _osd_wnt_set_error (myError, OSD_WFile);
1316 ImperativeFlag = Standard_True;
1320 #elif defined(POSIX)
1324 case OSD_ExclusiveLock:
1331 myError.SetValue (EINVAL, Iam, "SetLock");
1335 struct stat aStatBuf;
1336 if (fstat (myFileChannel, &aStatBuf) == -1)
1338 myError.SetValue (errno, Iam, "SetLock");
1342 const int aStatus = lockf (myFileChannel, aLock, aStatBuf.st_size);
1345 myError.SetValue (errno, Iam, "SetLock");
1352 struct flock aLockKey;
1353 aLockKey.l_whence = 0;
1354 aLockKey.l_start = 0;
1358 case OSD_ExclusiveLock:
1360 aLockKey.l_type = F_WRLCK;
1363 aLockKey.l_type = F_RDLCK;
1367 //default: myError.SetValue (EINVAL, Iam, "SetLock");
1370 const int aStatus = fcntl (myFileChannel, F_SETLKW, &aLockKey);
1373 myError.SetValue (errno, Iam, "SetLock");
1380 if (theLock == OSD_ExclusiveLock)
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;
1393 case OSD_ExclusiveLock:
1401 myError.SetValue (EINVAL, Iam, "SetLock");
1405 const int aStatus = flock (myFileChannel, aLock);
1408 myError.SetValue (errno, Iam, "SetLock");
1417 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1423 // =======================================================================
1424 // function : UnLock
1426 // =======================================================================
1427 void OSD_File::UnLock()
1431 throw Standard_ProgramError ("OSD_File::UnLock(): file is not open");
1436 LARGE_INTEGER aSize;
1437 aSize.QuadPart = Size();
1439 OVERLAPPED anOverlappedArea;
1440 anOverlappedArea.Offset = 0;
1441 anOverlappedArea.OffsetHigh = 0;
1442 if (!UnlockFileEx (myFileHandle, 0, aSize.LowPart, aSize.HighPart, &anOverlappedArea))
1444 _osd_wnt_set_error (myError, OSD_WFile);
1446 ImperativeFlag = Standard_False;
1448 #elif defined(POSIX)
1449 struct stat aStatBuf;
1450 if (fstat (myFileChannel, &aStatBuf) == -1)
1452 myError.SetValue (errno, Iam, "UnsetLock");
1456 const int aStatus = lockf (myFileChannel, F_ULOCK, aStatBuf.st_size);
1459 myError.SetValue (errno, Iam, "SetLock");
1463 myLock = OSD_NoLock;
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;
1476 struct flock aLockKey;
1477 aLockKey.l_type = F_UNLCK;
1478 const int aStatus = fcntl (myFileChannel, F_SETLK, &aLockKey);
1481 myError.SetValue (errno, Iam, "UnSetLock");
1485 myLock = OSD_NoLock;
1488 const int aStatus = flock (myFileChannel, LOCK_UN);
1491 myError.SetValue (errno, Iam, "UnSetLock");
1495 myLock = OSD_NoLock;
1500 // =======================================================================
1503 // =======================================================================
1504 Standard_Size OSD_File::Size()
1509 throw Standard_ProgramError ("OSD_File::Size(): file is not open");
1511 #if (_WIN32_WINNT >= 0x0500)
1512 LARGE_INTEGER aSize;
1514 if (GetFileSizeEx (myFileHandle, &aSize) == 0)
1516 _osd_wnt_set_error (myError, OSD_WFile);
1518 return (Standard_Size )aSize.QuadPart;
1520 DWORD aSize = GetFileSize (myFileHandle, NULL);
1521 if (aSize == INVALID_FILE_SIZE)
1523 _osd_wnt_set_error (myError, OSD_WFile);
1528 if (myPath.Name().Length() == 0)
1530 throw Standard_ProgramError ("OSD_File::Size(): empty file name");
1533 TCollection_AsciiString aFilePath;
1534 myPath.SystemName (aFilePath);
1536 struct stat aStatBuf;
1537 const int aStatus = stat (aFilePath.ToCString(), &aStatBuf);
1540 myError.SetValue (errno, Iam, "Size");
1543 return (Standard_Size )aStatBuf.st_size;
1547 // =======================================================================
1548 // function : IsOpen
1550 // =======================================================================
1551 Standard_Boolean OSD_File::IsOpen() const
1554 return myFileHandle != INVALID_HANDLE_VALUE;
1556 return myFileChannel != -1;
1560 // =======================================================================
1561 // function : IsReadable
1563 // =======================================================================
1564 Standard_Boolean OSD_File::IsReadable()
1566 TCollection_AsciiString aFileName;
1567 myPath.SystemName (aFileName);
1569 HANDLE aChannel = OSD_File_openFile (aFileName, OSD_ReadOnly, OPEN_OLD);
1570 if (aChannel == INVALID_HANDLE_VALUE)
1572 return Standard_False;
1575 CloseHandle (aChannel);
1576 return Standard_True;
1578 return access (aFileName.ToCString(), F_OK | R_OK) == 0;
1582 // =======================================================================
1583 // function : IsWriteable
1585 // =======================================================================
1586 Standard_Boolean OSD_File::IsWriteable()
1588 TCollection_AsciiString aFileName;
1589 myPath.SystemName (aFileName);
1591 HANDLE aChannel = OSD_File_openFile (aFileName, OSD_ReadWrite, OPEN_OLD);
1592 if (aChannel == INVALID_HANDLE_VALUE)
1594 return Standard_False;
1597 CloseHandle (aChannel);
1598 return Standard_True;
1600 return access (aFileName.ToCString(), F_OK | R_OK | W_OK) == 0;
1604 // =======================================================================
1605 // function : IsExecutable
1607 // =======================================================================
1608 Standard_Boolean OSD_File::IsExecutable()
1611 return IsReadable();
1613 TCollection_AsciiString aFileName;
1614 myPath.SystemName (aFileName);
1615 return access (aFileName.ToCString(), F_OK | X_OK) == 0;
1619 // =======================================================================
1620 // function : Rewind
1622 // =======================================================================
1623 void OSD_File::Rewind()
1626 LARGE_INTEGER aDistanceToMove;
1627 aDistanceToMove.QuadPart = 0;
1628 SetFilePointerEx (myFileHandle, aDistanceToMove, NULL, FILE_BEGIN);
1630 rewind ((FILE* )myFILE);
1634 // =======================================================================
1635 // function : ReadLastLine
1637 // =======================================================================
1638 Standard_Boolean OSD_File::ReadLastLine (TCollection_AsciiString& theLine,
1639 const Standard_Integer theDelay,
1640 const Standard_Integer theNbTries)
1642 if (theNbTries <= 0)
1644 return Standard_False;
1647 const Standard_Integer TheMaxLength = 1000;
1648 for (Standard_Integer Count = theNbTries; Count > 0; --Count)
1650 Standard_Integer aLen = 0;
1651 ReadLine (theLine, TheMaxLength, aLen);
1652 if (!theLine.IsEmpty())
1654 return Standard_True;
1656 OSD::SecSleep (theDelay);
1658 return Standard_False;
1661 // =======================================================================
1664 // =======================================================================
1665 Standard_Boolean OSD_File::Edit()
1667 std::cout << "Function OSD_File::Edit() not yet implemented.\n";
1668 return Standard_False;
1672 // None of the existing security APIs are supported in a UWP applications
1676 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1679 #define __leave return retVal
1682 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd (const OSD_Protection& theProtection, BOOL theIsDir, const wchar_t* theFileName)
1686 HANDLE hProcess = NULL;
1688 DWORD dwACLsize = sizeof(ACL);
1690 PTOKEN_OWNER pTkOwner = NULL;
1691 PTOKEN_GROUPS pTkGroups = NULL;
1692 PTOKEN_PRIMARY_GROUP pTkPrimaryGroup = NULL;
1693 PSECURITY_DESCRIPTOR retVal = NULL;
1694 PSECURITY_DESCRIPTOR pfSD = NULL;
1700 const int j = theIsDir ? 1 : 0;
1701 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &hProcess))
1705 if ((pTkGroups = (PTOKEN_GROUPS )GetTokenInformationEx (hProcess, TokenGroups)) == NULL)
1709 if ((pTkOwner = (PTOKEN_OWNER )GetTokenInformationEx (hProcess, TokenOwner)) == NULL)
1713 if ((pTkPrimaryGroup = (PTOKEN_PRIMARY_GROUP )GetTokenInformationEx (hProcess, TokenPrimaryGroup)) == NULL)
1719 if (theFileName == NULL)
1721 pSIDowner = pTkOwner->Owner;
1725 pfSD = GetFileSecurityEx (theFileName, OWNER_SECURITY_INFORMATION);
1726 if (pfSD == NULL || !GetSecurityDescriptorOwner (pfSD, &pSIDowner, &fDummy))
1733 PSID pSIDadmin = AdminSid();
1734 PSID pSIDworld = WorldSid();
1736 DWORD dwAccessAdmin = OSD_File_getAccessMask (theProtection.System());
1737 DWORD dwAccessGroup = OSD_File_getAccessMask (theProtection.Group());
1738 DWORD dwAccessOwner = OSD_File_getAccessMask (theProtection.User());
1739 DWORD dwAccessWorld = OSD_File_getAccessMask (theProtection.World());
1741 DWORD dwAccessAdminDir = OSD_File_getDirAccessMask (theProtection.System());
1742 //DWORD dwAccessGroupDir = OSD_File_getDirAccessMask (theProtection.Group());
1743 DWORD dwAccessOwnerDir = OSD_File_getDirAccessMask (theProtection.User());
1744 //DWORD dwAccessWorldDir = OSD_File_getDirAccessMask (theProtection.World());
1745 if (dwAccessGroup != 0)
1747 for (int aGroupIter = 0; aGroupIter < (int )pTkGroups->GroupCount; ++aGroupIter)
1749 PSID pSIDtemp = pTkGroups->Groups[aGroupIter].Sid;
1750 if (!NtPredefinedSid (pSIDtemp)
1751 && !EqualSid (pSIDtemp, pSIDworld)
1752 && !EqualSid (pSIDtemp, pTkPrimaryGroup->PrimaryGroup)
1753 && IsValidSid (pSIDtemp))
1755 dwACLsize += ((GetLengthSid (pSIDtemp) + ACE_HEADER_SIZE) << j);
1760 dwACLsize += (((GetLengthSid (pSIDowner) + ACE_HEADER_SIZE) << j)
1761 + ((GetLengthSid (pSIDadmin) + ACE_HEADER_SIZE) << j)
1762 + ((GetLengthSid (pSIDworld) + ACE_HEADER_SIZE) << j));
1763 if ((pACL = CreateAcl (dwACLsize)) == NULL)
1768 if (dwAccessAdmin != 0)
1770 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessAdmin, 0, pSIDadmin)) != NULL)
1772 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1775 pFileACE->dwMask = dwAccessAdminDir;
1776 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1777 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1783 if (dwAccessOwner != 0)
1785 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessOwner, 0, pSIDowner)) != NULL)
1787 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1790 pFileACE->dwMask = dwAccessOwnerDir;
1791 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1792 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1798 if (dwAccessWorld != 0)
1800 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessWorld, 0, pSIDworld)) != NULL)
1802 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1805 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1806 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1812 if (dwAccessGroup != 0)
1814 for (int aGroupIter = 0; aGroupIter < (int )pTkGroups->GroupCount; ++aGroupIter)
1816 PSID pSIDtemp = pTkGroups->Groups[aGroupIter].Sid;
1817 if (!NtPredefinedSid(pSIDtemp)
1818 && !EqualSid (pSIDtemp, pSIDworld)
1819 && !EqualSid (pSIDtemp, pTkPrimaryGroup->PrimaryGroup)
1820 && IsValidSid (pSIDtemp))
1822 if (dwAccessGroup != 0)
1824 if ((pFileACE = (PFILE_ACE )AllocAccessAllowedAce (dwAccessGroup, 0, pSIDtemp)) != NULL)
1826 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1829 pFileACE->header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
1830 AddAce (pACL, ACL_REVISION, dwIndex++, pFileACE, pFileACE->header.AceSize);
1839 if ((retVal = AllocSD()) == NULL)
1844 if (!SetSecurityDescriptorDacl (retVal, TRUE, pACL, TRUE))
1859 else if (pACL != NULL)
1866 if (hProcess != NULL)
1868 CloseHandle (hProcess);
1870 if (pTkOwner != NULL)
1872 FreeTokenInformation (pTkOwner);
1874 if (pTkGroups != NULL)
1876 FreeTokenInformation (pTkGroups);
1878 if (pTkPrimaryGroup != NULL)
1880 FreeTokenInformation (pTkPrimaryGroup);
1884 FreeFileSecurity (pfSD);
1891 BOOL __fastcall _osd_wnt_sd_to_protection (PSECURITY_DESCRIPTOR pSD, OSD_Protection& theProtection, BOOL theIsDir)
1893 BOOL fPresent = FALSE;
1894 BOOL fDefaulted = FALSE;
1897 BOOL retVal = FALSE;
1900 if (!GetSecurityDescriptorOwner (pSD, &pSIDowner, &fDefaulted))
1904 if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pACL, &fDefaulted)
1909 if (pSIDowner == NULL || pACL == NULL)
1911 SetLastError (ERROR_NO_SECURITY_ON_OBJECT);
1915 PSID pSIDadmin = AdminSid();
1916 PSID pSIDworld = WorldSid();
1917 DWORD dwAccessOwner = 0;
1918 DWORD dwAccessGroup = 0;
1919 DWORD dwAccessAdmin = 0;
1920 DWORD dwAccessWorld = 0;
1921 for (DWORD anAceIter = 0; anAceIter < pACL->AceCount; ++anAceIter)
1924 if (GetAce (pACL, anAceIter, &pACE))
1926 const DWORD dwAccess = ((PACE_HEADER )pACE)->AceType == ACCESS_DENIED_ACE_TYPE
1929 if (EqualSid (pSIDowner, GET_SID(pACE)))
1931 dwAccessOwner = dwAccess;
1933 else if (EqualSid (pSIDadmin, GET_SID(pACE)))
1935 dwAccessAdmin = dwAccess;
1937 else if (EqualSid (pSIDworld, GET_SID(pACE)))
1939 dwAccessWorld = dwAccess;
1943 dwAccessGroup = dwAccess;
1948 typedef OSD_SingleProtection (*OSD_File_getProtection_t)(DWORD );
1949 OSD_File_getProtection_t aGetProtFunc = theIsDir ? &OSD_File_getProtectionDir : &OSD_File_getProtection;
1950 theProtection.SetValues (aGetProtFunc (dwAccessAdmin),
1951 aGetProtFunc (dwAccessOwner),
1952 aGetProtFunc (dwAccessGroup),
1953 aGetProtFunc (dwAccessWorld));
1959 } // end _osd_wnt_sd_to_protection
1961 #if defined(__CYGWIN32__) || defined(__MINGW32__)