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 | // ======================================================================= |
366 | OSD_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 | // ======================================================================= |
385 | OSD_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 | // ======================================================================= |
405 | OSD_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 | // ======================================================================= |
421 | void 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 | // ======================================================================= |
497 | void 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 | // ======================================================================= |
588 | void 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 | // ======================================================================= |
660 | void 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 | // ======================================================================= |
752 | void 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 | // ======================================================================= |
807 | void 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 | // ======================================================================= |
986 | OSD_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 | // ======================================================================= |
1025 | void 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 | // ======================================================================= |
1097 | void 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 | // ======================================================================= |
1146 | void 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 | // ======================================================================= |
1204 | void 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 | // ======================================================================= |
1238 | Standard_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 | // ======================================================================= |
1281 | void 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 | // ======================================================================= |
1423 | void 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 | // ======================================================================= |
1500 | Standard_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 | // ======================================================================= |
1547 | Standard_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 | // ======================================================================= |
1560 | Standard_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 | // ======================================================================= |
1582 | Standard_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 | // ======================================================================= |
1604 | Standard_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 | // ======================================================================= |
1619 | void 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 | // ======================================================================= |
1634 | Standard_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 | // ======================================================================= |
1661 | Standard_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 | |
1678 | PSECURITY_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 |
1714 | retry: |
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 |
1887 | BOOL __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 */ |