b311480e |
1 | // Created by: PLOTNIKOV Eugeny |
2 | // Copyright (c) 1996-1999 Matra Datavision |
973c2be1 |
3 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
b311480e |
15 | |
57c28b61 |
16 | #ifdef _WIN32 |
7fd59977 |
17 | |
7fd59977 |
18 | /******************************************************************************/ |
19 | /* File: OSD_WNT.cxx */ |
20 | /* Purpose: Security management routines ( more convinient than WIN32 */ |
21 | /* ones ) and other convinient functions. */ |
7fd59977 |
22 | /******************************************************************************/ |
23 | /***/ |
68df8478 |
24 | #include <OSD_WNT.hxx> |
7fd59977 |
25 | |
5fecc495 |
26 | #include <strsafe.h> |
d9ff84e8 |
27 | #include <wchar.h> |
7fd59977 |
28 | #include <stdlib.h> |
742cc8b0 |
29 | |
30 | #include <Standard_Macro.hxx> |
31 | |
7fd59977 |
32 | /***/ |
742cc8b0 |
33 | #ifndef OCCT_UWP |
7fd59977 |
34 | static void Init ( void ); |
35 | /***/ |
7fd59977 |
36 | class Init_OSD_WNT { // provides initialization |
37 | |
38 | public: |
39 | |
68299304 |
40 | Init_OSD_WNT () { Init (); } |
7fd59977 |
41 | |
42 | }; // end Init_OSD_WNT |
43 | |
44 | static Init_OSD_WNT initOsdWnt; |
742cc8b0 |
45 | #endif |
7fd59977 |
46 | /***/ |
47 | static BOOL fInit = FALSE; |
48 | static PSID* predefinedSIDs; |
49 | static HANDLE hHeap; |
50 | /***/ |
7fd59977 |
51 | static MOVE_DIR_PROC _move_dir_proc; |
52 | static COPY_DIR_PROC _copy_dir_proc; |
53 | static RESPONSE_DIR_PROC _response_dir_proc; |
54 | /***/ |
55 | #define PREDEFINED_SIDs_COUNT 9 |
56 | #define UNIVERSAL_PREDEFINED_SIDs_COUNT 5 |
57 | /***/ |
58 | #define SID_INTERACTIVE 0 |
59 | #define SID_NETWORK 1 |
60 | #define SID_LOCAL 2 |
61 | #define SID_DIALUP 3 |
62 | #define SID_BATCH 4 |
63 | #define SID_CREATOR_OWNER 5 |
64 | #define SID_ADMIN 6 |
65 | #define SID_WORLD 7 |
66 | #define SID_NULL 8 |
67 | /***/ |
742cc8b0 |
68 | #ifndef OCCT_UWP |
69 | // None of the existing security APIs are supported in a UWP applications |
7fd59977 |
70 | /******************************************************************************/ |
71 | /* Function : AllocSD */ |
72 | /* Purpose : Allocates and initializes security identifier */ |
73 | /* Returns : Pointer to allocated SID on success, NULL otherwise */ |
74 | /* Warning : Allocated SID must be deallocated by 'FreeSD' function */ |
75 | /******************************************************************************/ |
76 | /***/ |
77 | PSECURITY_DESCRIPTOR AllocSD ( void ) { |
78 | |
79 | PSECURITY_DESCRIPTOR retVal = |
80 | ( PSECURITY_DESCRIPTOR )HeapAlloc ( |
81 | hHeap, 0, sizeof ( SECURITY_DESCRIPTOR ) |
82 | ); |
83 | |
84 | if ( retVal != NULL && |
85 | !InitializeSecurityDescriptor ( retVal, SECURITY_DESCRIPTOR_REVISION ) |
86 | ) { |
87 | |
88 | HeapFree ( hHeap, 0, ( PVOID )retVal ); |
89 | retVal = NULL; |
90 | |
91 | } /* end if */ |
92 | |
93 | return retVal; |
94 | |
95 | } /* end AllocSD */ |
96 | /***/ |
97 | /******************************************************************************/ |
98 | /* Function : FreeSD */ |
99 | /* Purpose : Deallocates security identifier which was allocated by the */ |
100 | /* 'AllocSD' function */ |
101 | /******************************************************************************/ |
102 | /***/ |
103 | void FreeSD ( PSECURITY_DESCRIPTOR pSD ) { |
104 | |
105 | BOOL fPresent; |
106 | BOOL fDaclDefaulted; |
107 | PACL pACL; |
108 | |
109 | if ( GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDaclDefaulted ) && |
110 | fPresent |
111 | ) |
112 | |
113 | HeapFree ( hHeap, 0, ( PVOID )pACL ); |
114 | |
115 | HeapFree ( hHeap, 0, ( PVOID )pSD ); |
116 | |
117 | } /* end FreeSD */ |
118 | /***/ |
119 | /******************************************************************************/ |
120 | /* Function : GetTokenInformationEx */ |
121 | /* Purpose : Allocates and fills out access token */ |
122 | /* Returns : Pointer to the access token on success, NULL otherwise */ |
123 | /* Warning : Allocated access token must be deallocated by */ |
124 | /* 'FreeTokenInformation' function */ |
125 | /******************************************************************************/ |
126 | /***/ |
127 | |
128 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
129 | #define __try |
130 | #define __finally |
131 | #define __leave return buffer |
132 | #endif |
133 | |
134 | LPVOID GetTokenInformationEx ( HANDLE hToken, TOKEN_INFORMATION_CLASS tic ) { |
135 | |
136 | DWORD errVal; |
137 | DWORD dwSize; |
138 | DWORD dwSizeNeeded = 0; |
139 | LPVOID buffer = NULL; |
140 | BOOL fOK = FALSE; |
141 | |
142 | __try { |
143 | |
144 | do { |
145 | |
146 | dwSize = dwSizeNeeded; |
147 | errVal = ERROR_SUCCESS; |
148 | |
149 | if ( !GetTokenInformation ( hToken, tic, buffer, dwSize, &dwSizeNeeded ) ) { |
150 | |
151 | if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER ) |
152 | |
153 | __leave; |
154 | |
155 | if ( ( buffer = HeapAlloc ( hHeap, 0, dwSizeNeeded ) ) == NULL ) |
156 | |
157 | __leave; |
158 | |
159 | } /* end if */ |
160 | |
161 | } while ( errVal != ERROR_SUCCESS ); |
162 | |
163 | fOK = TRUE; |
164 | |
165 | } /* end __try */ |
166 | |
167 | __finally { |
168 | |
169 | if ( !fOK && buffer != NULL ) { |
170 | |
171 | HeapFree ( hHeap, 0, buffer ); |
172 | buffer = NULL; |
173 | |
174 | } /* end if */ |
175 | |
176 | } /* end __finally */ |
177 | |
178 | #ifdef VAC |
179 | leave: ; // added for VisualAge |
180 | #endif |
181 | |
182 | return buffer; |
183 | |
184 | } /* end GetTokenInformationEx */ |
185 | |
186 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
187 | #undef __try |
188 | #undef __finally |
189 | #undef __leave |
190 | #endif |
191 | |
192 | /***/ |
193 | /******************************************************************************/ |
194 | /* Function : FreeTokenInformation */ |
195 | /* Purpose : Deallocates access token which was allocated by the */ |
196 | /* 'GetTokenInformationEx' function */ |
197 | /******************************************************************************/ |
198 | /***/ |
199 | void FreeTokenInformation ( LPVOID lpvTkInfo ) { |
200 | |
201 | HeapFree ( hHeap, 0, lpvTkInfo ); |
202 | |
203 | } /* end FreeTokenInformation */ |
204 | /***/ |
205 | /******************************************************************************/ |
206 | /* Function : Init */ |
207 | /* Purpose : Allocates and initializes predefined security identifiers */ |
208 | /* Warning : Generates 'STATUS_NO_MEMORY' software exception if there are */ |
209 | /* insufficient of memory. This exception can be caught by using */ |
210 | /* software exception handling ( SEH ) mechanism */ |
211 | /* ( __try / __except ) */ |
212 | /******************************************************************************/ |
213 | /***/ |
214 | static void Init ( void ) { |
215 | |
216 | SID_IDENTIFIER_AUTHORITY sidIDAnull = SECURITY_NULL_SID_AUTHORITY; |
217 | SID_IDENTIFIER_AUTHORITY sidIDAworld = SECURITY_WORLD_SID_AUTHORITY; |
218 | SID_IDENTIFIER_AUTHORITY sidIDANT = SECURITY_NT_AUTHORITY; |
219 | SID_IDENTIFIER_AUTHORITY sidIDAlocal = SECURITY_LOCAL_SID_AUTHORITY; |
220 | SID_IDENTIFIER_AUTHORITY sidIDAcreator = SECURITY_CREATOR_SID_AUTHORITY; |
221 | |
222 | if ( !fInit ) { |
223 | |
224 | predefinedSIDs = ( PSID* )HeapAlloc ( |
225 | hHeap = GetProcessHeap (), |
226 | HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, |
227 | PREDEFINED_SIDs_COUNT * sizeof ( PSID* ) |
228 | ); |
229 | |
230 | AllocateAndInitializeSid ( |
231 | &sidIDANT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, |
232 | 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_ADMIN ] |
233 | ); |
234 | |
235 | AllocateAndInitializeSid ( |
236 | &sidIDAworld, 1, SECURITY_WORLD_RID, |
237 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_WORLD ] |
238 | ); |
239 | |
240 | AllocateAndInitializeSid ( |
241 | &sidIDANT, 1, SECURITY_INTERACTIVE_RID, |
242 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_INTERACTIVE ] |
243 | ); |
244 | |
245 | AllocateAndInitializeSid ( |
246 | &sidIDANT, 1, SECURITY_NETWORK_RID, |
247 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NETWORK ] |
248 | ); |
249 | |
250 | AllocateAndInitializeSid ( |
251 | &sidIDAlocal, 1, SECURITY_LOCAL_RID, |
252 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_LOCAL ] |
253 | ); |
254 | |
255 | AllocateAndInitializeSid ( |
256 | &sidIDANT, 1, SECURITY_DIALUP_RID, |
257 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_DIALUP ] |
258 | ); |
259 | |
260 | AllocateAndInitializeSid ( |
261 | &sidIDANT, 1, SECURITY_BATCH_RID, |
262 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_BATCH ] |
263 | ); |
264 | |
265 | AllocateAndInitializeSid ( |
266 | &sidIDAcreator, 1, SECURITY_CREATOR_OWNER_RID, |
267 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_CREATOR_OWNER ] |
268 | ); |
269 | |
270 | AllocateAndInitializeSid ( |
271 | &sidIDAnull, 1, SECURITY_NULL_RID, |
272 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NULL ] |
273 | ); |
274 | |
275 | fInit = TRUE; |
276 | |
277 | } /* end if */ |
278 | |
279 | } /* end init */ |
280 | /***/ |
281 | /******************************************************************************/ |
282 | /* Function : PredefinedSid */ |
283 | /* Purpose : Checks whether specified SID predefined or not */ |
284 | /* Returns : TRUE if specified SID is predefined, FALSE otherwise */ |
285 | /******************************************************************************/ |
286 | /***/ |
287 | BOOL PredefinedSid ( PSID pSID ) { |
288 | |
289 | int i; |
290 | |
291 | for ( i = 0; i < PREDEFINED_SIDs_COUNT; ++i ) |
292 | |
293 | if ( EqualSid ( pSID, predefinedSIDs[ i ] ) ) |
294 | |
295 | return TRUE; |
296 | |
297 | return FALSE; |
298 | |
299 | } /* end PredefinedSid */ |
300 | /***/ |
301 | /******************************************************************************/ |
302 | /* Function : NtPredefinedSid */ |
303 | /* Purpose : Checks whether specified SID universal or not */ |
304 | /* Returns : TRUE if specified SID is NOT universal, FALSE otherwise */ |
305 | /******************************************************************************/ |
306 | /***/ |
307 | BOOL NtPredefinedSid ( PSID pSID ) { |
308 | |
309 | int i; |
310 | PSID_IDENTIFIER_AUTHORITY pTestIDA; |
311 | SID_IDENTIFIER_AUTHORITY ntIDA = SECURITY_NT_AUTHORITY; |
312 | PDWORD pdwTestSA; |
313 | |
314 | for ( i = 0; i < UNIVERSAL_PREDEFINED_SIDs_COUNT; ++i ) |
315 | |
316 | if ( EqualSid ( pSID, predefinedSIDs[ i ] ) ) |
317 | |
318 | return TRUE; |
319 | |
320 | pTestIDA = GetSidIdentifierAuthority ( pSID ); |
321 | |
322 | if ( memcmp ( pTestIDA, &ntIDA, sizeof ( SID_IDENTIFIER_AUTHORITY ) ) == 0 ) { |
323 | |
324 | pdwTestSA = GetSidSubAuthority ( pSID, 0 ); |
325 | |
326 | if ( *pdwTestSA == SECURITY_LOGON_IDS_RID ) |
327 | |
328 | return TRUE; |
329 | |
330 | } /* end if */ |
331 | |
332 | return FALSE; |
333 | |
334 | } /* end NtPredefinedSid */ |
335 | /***/ |
336 | /******************************************************************************/ |
337 | /* Function : AdminSid */ |
338 | /* Purpose : Returns SID of the administrative user account */ |
339 | /******************************************************************************/ |
340 | /***/ |
341 | PSID AdminSid ( void ) { |
342 | |
343 | return predefinedSIDs[ SID_ADMIN ]; |
344 | |
345 | } /* end AdminSid */ |
346 | /***/ |
347 | /******************************************************************************/ |
348 | /* Function : WorldSid */ |
349 | /* Purpose : Returns SID of group that includes all users */ |
350 | /******************************************************************************/ |
351 | /***/ |
352 | PSID WorldSid ( void ) { |
353 | |
354 | return predefinedSIDs[ SID_WORLD ]; |
355 | |
356 | } /* end WorldSid */ |
357 | /***/ |
358 | /******************************************************************************/ |
359 | /* Function : InteractiveSid */ |
360 | /* Purpose : Returns SID of group that includes all users logged on for */ |
361 | /* interactive operation */ |
362 | /******************************************************************************/ |
363 | /***/ |
364 | PSID InteractiveSid ( void ) { |
365 | |
366 | return predefinedSIDs[ SID_INTERACTIVE ]; |
367 | |
368 | } /* end InteractiveSID */ |
369 | /***/ |
370 | /******************************************************************************/ |
371 | /* Function : NetworkSid */ |
372 | /* Purpose : Returns SID of group that includes all users logged on across */ |
373 | /* a network */ |
374 | /******************************************************************************/ |
375 | /***/ |
376 | PSID NetworkSid ( void ) { |
377 | |
378 | return predefinedSIDs[ SID_NETWORK ]; |
379 | |
380 | } /* end NetworkSid */ |
381 | /***/ |
382 | /******************************************************************************/ |
383 | /* Function : LocalSid */ |
384 | /* Purpose : Returns SID of group that includes all users logged on locally*/ |
385 | /******************************************************************************/ |
386 | /***/ |
387 | PSID LocalSid ( void ) { |
388 | |
389 | return predefinedSIDs[ SID_LOCAL ]; |
390 | |
391 | } /* end LocalSid */ |
392 | /***/ |
393 | /******************************************************************************/ |
394 | /* Function : DialupSid */ |
395 | /* Purpose : Returns SID of group that includes all users logged on to */ |
396 | /* terminals using a dialup modem */ |
397 | /******************************************************************************/ |
398 | /***/ |
399 | PSID DialupSid ( void ) { |
400 | |
401 | return predefinedSIDs[ SID_DIALUP ]; |
402 | |
403 | } /* end DialupSid */ |
404 | /***/ |
405 | /******************************************************************************/ |
406 | /* Function : BatchSid */ |
407 | /* Purpose : Returns SID of group that includes all users logged on using */ |
408 | /* a batch queue facility */ |
409 | /******************************************************************************/ |
410 | /***/ |
411 | PSID BatchSid ( void ) { |
412 | |
413 | return predefinedSIDs[ SID_BATCH ]; |
414 | |
415 | } /* end BatchSid */ |
416 | /***/ |
417 | /******************************************************************************/ |
418 | /* Function : CreatorOwnerSid */ |
419 | /* Purpose : Returns SID of 'CREATOR OWNER' special group */ |
420 | /******************************************************************************/ |
421 | /***/ |
422 | PSID CreatorOwnerSid ( void ) { |
423 | |
424 | return predefinedSIDs[ SID_CREATOR_OWNER ]; |
425 | |
426 | } /* end CreatorOwnerSid */ |
427 | /***/ |
428 | /******************************************************************************/ |
429 | /* Function : NullSid */ |
430 | /* Purpose : Returns null SID */ |
431 | /******************************************************************************/ |
432 | /***/ |
433 | PSID NullSid ( void ) { |
434 | |
435 | return predefinedSIDs[ SID_NULL ]; |
436 | |
437 | } /* end NullSid */ |
438 | /***/ |
439 | /******************************************************************************/ |
440 | /* Function : GetFileSecurityEx */ |
441 | /* Purpose : Allocates a security descriptor and fills it out by security */ |
442 | /* information which belongs to the specified file */ |
443 | /* Returns : Pointer to the allocated security descriptor on success */ |
444 | /* NULL otherwise */ |
445 | /* Warning : Allocated security descriptor must be deallocated by */ |
446 | /* 'FreeFileSecurity' function */ |
447 | /******************************************************************************/ |
448 | /***/ |
449 | |
450 | |
451 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
452 | #define __try |
453 | #define __finally |
454 | #define __leave return retVal |
455 | #endif |
456 | |
d9ff84e8 |
457 | PSECURITY_DESCRIPTOR GetFileSecurityEx ( LPCWSTR fileName, SECURITY_INFORMATION si ) { |
7fd59977 |
458 | |
459 | DWORD errVal; |
460 | DWORD dwSize; |
461 | DWORD dwSizeNeeded = 0; |
462 | PSECURITY_DESCRIPTOR retVal = NULL; |
463 | BOOL fOK = FALSE; |
464 | |
465 | __try { |
466 | |
467 | do { |
468 | |
469 | dwSize = dwSizeNeeded; |
470 | errVal = ERROR_SUCCESS; |
471 | |
d9ff84e8 |
472 | if ( !GetFileSecurityW ( |
7fd59977 |
473 | fileName, si, |
474 | retVal, dwSize, &dwSizeNeeded |
475 | ) |
476 | ) { |
477 | |
478 | if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER ) __leave; |
479 | |
480 | if ( ( retVal = ( PSECURITY_DESCRIPTOR )HeapAlloc ( hHeap, 0, dwSizeNeeded ) |
481 | ) == NULL |
482 | ) __leave; |
483 | |
484 | } /* end if */ |
485 | |
486 | } while ( errVal != ERROR_SUCCESS ); |
487 | |
488 | fOK = TRUE; |
489 | |
490 | } /* end __try */ |
491 | |
492 | __finally { |
493 | |
494 | if ( !fOK && retVal != NULL ) { |
495 | |
496 | HeapFree ( hHeap, 0, retVal ); |
497 | retVal = NULL; |
498 | |
499 | } /* end if */ |
500 | |
501 | } /* end __finally */ |
502 | |
503 | #ifdef VAC |
504 | leave: ; // added for VisualAge |
505 | #endif |
506 | |
507 | return retVal; |
508 | |
509 | } /* end GetFileSecurityEx */ |
510 | |
511 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
512 | #undef __try |
513 | #undef __finally |
514 | #undef __leave |
515 | #endif |
516 | |
517 | /***/ |
518 | /******************************************************************************/ |
519 | /* Function : FreeFileSecurity */ |
520 | /* Purpose : Deallocates security descriptor which was allocated by the */ |
521 | /* 'GetFileSecurityEx' function */ |
522 | /******************************************************************************/ |
523 | /***/ |
524 | void FreeFileSecurity ( PSECURITY_DESCRIPTOR pSD ) { |
525 | |
526 | HeapFree ( hHeap, 0, ( LPVOID )pSD ); |
527 | |
528 | } /* end FreeFileSecurity */ |
7fd59977 |
529 | |
7fd59977 |
530 | |
7fd59977 |
531 | /******************************************************************************/ |
532 | /* Function : CreateAcl */ |
533 | /* Purpose : Allocates and initializes access-control list */ |
534 | /* Returns : Pointer to the allocated and initialized ACL on success, */ |
535 | /* NULL otherwise */ |
536 | /* Warning : Allocated ACL must be deallocated by 'FreeAcl' function */ |
537 | /******************************************************************************/ |
538 | /***/ |
539 | PACL CreateAcl ( DWORD dwAclSize ) { |
540 | |
541 | PACL retVal; |
542 | |
543 | retVal = ( PACL )HeapAlloc ( hHeap, 0, dwAclSize ); |
544 | |
545 | if ( retVal != NULL ) |
546 | |
547 | InitializeAcl ( retVal, dwAclSize, ACL_REVISION ); |
548 | |
549 | return retVal; |
550 | |
551 | } /* end CreateAcl */ |
552 | /***/ |
553 | /******************************************************************************/ |
554 | /* Function : FreeAcl */ |
555 | /* Purpose : Deallocates access-control list which was allocated by the */ |
556 | /* 'CreateAcl' function */ |
557 | /******************************************************************************/ |
558 | /***/ |
559 | void FreeAcl ( PACL pACL ) { |
560 | |
561 | HeapFree ( hHeap, 0, ( PVOID )pACL ); |
562 | |
563 | } /* end FreeAcl */ |
7fd59977 |
564 | |
7fd59977 |
565 | /******************************************************************************/ |
566 | /* Function : AllocAccessAllowedAce */ |
567 | /* Purpose : Allocates and initializes access-control entry */ |
568 | /* Returns : Pointer to the ACE on success, NULL othrwise */ |
569 | /* Warning : Allocated ACE must be deallocated by the 'FreeAce' function */ |
570 | /******************************************************************************/ |
571 | /***/ |
572 | PVOID AllocAccessAllowedAce ( DWORD dwMask, BYTE flags, PSID pSID ) { |
573 | |
574 | PFILE_ACE retVal; |
575 | WORD wSize; |
576 | |
577 | wSize = (WORD)( sizeof ( ACE_HEADER ) + sizeof ( DWORD ) + GetLengthSid ( pSID ) ); |
578 | |
579 | retVal = ( PFILE_ACE )HeapAlloc ( hHeap, 0, wSize ); |
580 | |
581 | if ( retVal != NULL ) { |
582 | |
583 | retVal -> header.AceType = ACCESS_ALLOWED_ACE_TYPE; |
584 | retVal -> header.AceFlags = flags; |
585 | retVal -> header.AceSize = wSize; |
586 | |
587 | retVal -> dwMask = dwMask; |
588 | |
589 | CopySid ( GetLengthSid ( pSID ), &retVal -> pSID, pSID ); |
590 | |
591 | } /* end if */ |
592 | |
593 | return retVal; |
594 | |
595 | } /* end AllocAccessAllowedAce */ |
596 | /***/ |
597 | /******************************************************************************/ |
598 | /* Function : FreeAce */ |
599 | /* Purpose : Deallocates an ACE which was allocated by the */ |
600 | /* 'AllocAccessAllowedAce ' function */ |
601 | /******************************************************************************/ |
602 | /***/ |
603 | void FreeAce ( PVOID pACE ) { |
604 | |
605 | HeapFree ( hHeap, 0, pACE ); |
606 | |
607 | } /* end FreeAce */ |
742cc8b0 |
608 | #endif |
d9ff84e8 |
609 | #define WILD_CARD L"/*.*" |
7fd59977 |
610 | #define WILD_CARD_LEN ( sizeof ( WILD_CARD ) ) |
611 | |
7fd59977 |
612 | /***/ |
613 | /******************************************************************************/ |
614 | /* Function : MoveDirectory */ |
615 | /* Purpose : Moves specified directory tree to the new location */ |
616 | /* Returns : TRUE on success, FALSE otherwise */ |
617 | /******************************************************************************/ |
618 | /***/ |
c0f08310 |
619 | static BOOL MoveDirectory (const wchar_t* oldDir, const wchar_t* newDir, DWORD& theRecurseLevel) |
620 | { |
621 | wchar_t* driveSrc = NULL; |
622 | wchar_t* driveDst = NULL; |
623 | wchar_t* pathSrc = NULL; |
624 | wchar_t* pathDst = NULL; |
625 | BOOL retVal = FALSE; |
626 | if (theRecurseLevel == 0) |
627 | { |
628 | ++theRecurseLevel; |
629 | BOOL fFind = FALSE; |
630 | if ((driveSrc = (wchar_t* )HeapAlloc (hHeap, 0, _MAX_DRIVE * sizeof(wchar_t))) != NULL |
631 | && (driveDst = (wchar_t* )HeapAlloc (hHeap, 0, _MAX_DRIVE * sizeof(wchar_t))) != NULL |
632 | && (pathSrc = (wchar_t* )HeapAlloc (hHeap, 0, _MAX_DIR * sizeof(wchar_t))) != NULL |
633 | && (pathDst = (wchar_t* )HeapAlloc (hHeap, 0, _MAX_DIR * sizeof(wchar_t))) != NULL) |
634 | { |
635 | _wsplitpath (oldDir, driveSrc, pathSrc, NULL, NULL); |
636 | _wsplitpath (newDir, driveDst, pathDst, NULL, NULL); |
637 | if (wcscmp (driveSrc, driveDst) == 0 |
638 | && wcscmp (pathSrc, pathDst ) == 0) |
639 | { |
640 | retry: |
641 | retVal = MoveFileExW (oldDir, newDir, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); |
642 | fFind = TRUE; |
643 | if (!retVal) |
644 | { |
645 | if (_response_dir_proc != NULL) |
646 | { |
647 | const DIR_RESPONSE response = _response_dir_proc (oldDir); |
648 | if (response == DIR_RETRY) |
649 | { |
650 | goto retry; |
651 | } |
652 | else if (response == DIR_IGNORE) |
653 | { |
654 | retVal = TRUE; |
655 | } |
656 | } |
657 | } |
658 | else if (_move_dir_proc != NULL) |
659 | { |
660 | _move_dir_proc (oldDir, newDir); |
661 | } |
662 | } |
663 | } |
664 | |
665 | if (pathDst != NULL) |
666 | { |
667 | HeapFree (hHeap, 0, pathDst); |
668 | } |
669 | if (pathSrc != NULL) |
670 | { |
671 | HeapFree (hHeap, 0, pathSrc); |
672 | } |
673 | if (driveDst != NULL) |
674 | { |
675 | HeapFree (hHeap, 0, driveDst); |
676 | } |
677 | if (driveSrc != NULL) |
678 | { |
679 | HeapFree (hHeap, 0, driveSrc); |
680 | } |
681 | |
682 | if (fFind) |
683 | { |
684 | --theRecurseLevel; |
685 | return retVal; |
686 | } |
687 | } |
688 | else |
689 | { |
690 | ++theRecurseLevel; |
691 | } |
692 | |
693 | WIN32_FIND_DATAW* pFD = NULL; |
694 | wchar_t* pName = NULL; |
695 | wchar_t* pFullNameSrc = NULL; |
696 | wchar_t* pFullNameDst = NULL; |
697 | HANDLE hFindFile = INVALID_HANDLE_VALUE; |
698 | retVal = CreateDirectoryW (newDir, NULL); |
699 | if (retVal || (!retVal && GetLastError() == ERROR_ALREADY_EXISTS)) |
700 | { |
701 | size_t anOldDirLength; |
702 | StringCchLengthW (oldDir, sizeof(oldDir) / sizeof(oldDir[0]), &anOldDirLength); |
703 | if ((pFD = (WIN32_FIND_DATAW* )HeapAlloc (hHeap, 0, sizeof(WIN32_FIND_DATAW))) != NULL |
704 | && (pName = (wchar_t* )HeapAlloc (hHeap, 0, anOldDirLength + WILD_CARD_LEN + sizeof(L'\x00'))) != NULL) |
705 | { |
706 | StringCchCopyW (pName, sizeof(pName) / sizeof(pName[0]), oldDir); |
707 | StringCchCatW (pName, sizeof(pName), WILD_CARD); |
708 | retVal = TRUE; |
709 | hFindFile = FindFirstFileExW (pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0); |
710 | for (BOOL fFind = hFindFile != INVALID_HANDLE_VALUE; fFind; fFind = FindNextFileW (hFindFile, pFD)) |
711 | { |
712 | if ((pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'\0') |
713 | || (pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'.' && pFD->cFileName[2] == L'\0')) |
714 | { |
715 | continue; |
716 | } |
717 | |
718 | size_t anOldDirLength2 = 0, aNewDirLength = 0, aFileNameLength = 0; |
719 | StringCchLengthW (oldDir, sizeof(oldDir) / sizeof(oldDir[0]), &anOldDirLength2); |
720 | StringCchLengthW (newDir, sizeof(newDir) / sizeof(newDir[0]), &aNewDirLength); |
721 | StringCchLengthW (pFD->cFileName, sizeof(pFD->cFileName) / sizeof(pFD->cFileName[0]), &aFileNameLength); |
722 | if ((pFullNameSrc = (wchar_t* )HeapAlloc (hHeap, 0, anOldDirLength2 + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL |
723 | || (pFullNameDst = (wchar_t* )HeapAlloc (hHeap, 0, aNewDirLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL) |
724 | { |
725 | break; |
726 | } |
727 | |
728 | StringCchCopyW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), oldDir); |
729 | StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), L"/"); |
730 | StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), pFD->cFileName); |
731 | |
732 | StringCchCopyW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), newDir); |
733 | StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), L"/"); |
734 | StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), pFD->cFileName); |
735 | |
736 | if ((pFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) |
737 | { |
738 | retVal = MoveDirectory (pFullNameSrc, pFullNameDst, theRecurseLevel); |
739 | if (!retVal) |
740 | { |
741 | break; |
742 | } |
743 | } |
7fd59977 |
744 | else |
c0f08310 |
745 | { |
746 | retry_1: |
747 | retVal = MoveFileExW (pFullNameSrc, pFullNameDst, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); |
748 | if (!retVal) |
749 | { |
750 | if (_response_dir_proc != NULL) |
751 | { |
752 | const DIR_RESPONSE response = _response_dir_proc (pFullNameSrc); |
753 | if (response == DIR_ABORT) |
754 | { |
755 | break; |
756 | } |
757 | else if (response == DIR_RETRY) |
758 | { |
759 | goto retry_1; |
760 | } |
761 | else if (response == DIR_IGNORE) |
762 | { |
763 | retVal = TRUE; |
764 | } |
765 | else |
766 | { |
767 | break; |
768 | } |
769 | } |
770 | } |
771 | else if (_move_dir_proc != NULL) |
772 | { |
773 | _move_dir_proc (pFullNameSrc, pFullNameDst); |
774 | } |
775 | } |
776 | |
777 | HeapFree (hHeap, 0, pFullNameDst); |
778 | HeapFree (hHeap, 0, pFullNameSrc); |
779 | pFullNameSrc = pFullNameDst = NULL; |
780 | } |
781 | } |
782 | } |
783 | |
784 | if (hFindFile != INVALID_HANDLE_VALUE) |
785 | { |
786 | FindClose (hFindFile); |
787 | } |
788 | |
789 | if (pFullNameSrc != NULL) |
790 | { |
791 | HeapFree (hHeap, 0, pFullNameSrc); |
792 | } |
793 | if (pFullNameDst != NULL) |
794 | { |
795 | HeapFree (hHeap, 0, pFullNameDst); |
796 | } |
797 | if (pName != NULL) |
798 | { |
799 | HeapFree (hHeap, 0, pName); |
800 | } |
801 | if (pFD != NULL) |
802 | { |
803 | HeapFree (hHeap, 0, pFD); |
804 | } |
805 | |
806 | if (retVal) |
807 | { |
808 | retry_2: |
809 | retVal = RemoveDirectoryW (oldDir); |
810 | if (!retVal) |
811 | { |
812 | if (_response_dir_proc != NULL) |
813 | { |
814 | const DIR_RESPONSE response = _response_dir_proc (oldDir); |
815 | if (response == DIR_RETRY) |
816 | { |
817 | goto retry_2; |
818 | } |
819 | else if (response == DIR_IGNORE) |
820 | { |
821 | retVal = TRUE; |
822 | } |
823 | } |
824 | } |
825 | } |
826 | |
827 | --theRecurseLevel; |
828 | return retVal; |
829 | } |
7fd59977 |
830 | |
c0f08310 |
831 | BOOL MoveDirectory (const wchar_t* oldDir, const wchar_t* newDir) |
68299304 |
832 | { |
833 | DWORD aRecurseLevel = 0; |
834 | return MoveDirectory (oldDir, newDir, aRecurseLevel); |
835 | } |
836 | |
7fd59977 |
837 | /***/ |
838 | /******************************************************************************/ |
839 | /* Function : CopyDirectory */ |
840 | /* Purpose : Copies specified directory tree to the new location */ |
841 | /* Returns : TRUE on success, FALSE otherwise */ |
842 | /******************************************************************************/ |
843 | /***/ |
c0f08310 |
844 | BOOL CopyDirectory (const wchar_t* dirSrc, const wchar_t* dirDst) |
845 | { |
846 | WIN32_FIND_DATAW* pFD = NULL; |
847 | wchar_t* pName = NULL; |
848 | wchar_t* pFullNameSrc = NULL; |
849 | wchar_t* pFullNameDst = NULL; |
850 | HANDLE hFindFile = INVALID_HANDLE_VALUE; |
851 | |
852 | BOOL retVal = CreateDirectoryW (dirDst, NULL); |
853 | if (retVal || (!retVal && GetLastError() == ERROR_ALREADY_EXISTS)) |
854 | { |
855 | size_t aDirSrcLength = 0; |
856 | StringCchLengthW (dirSrc, sizeof(dirSrc) / sizeof(dirSrc[0]), &aDirSrcLength); |
857 | if ((pFD = (WIN32_FIND_DATAW* )HeapAlloc (hHeap, 0, sizeof(WIN32_FIND_DATAW))) != NULL |
858 | && (pName = (wchar_t* )HeapAlloc (hHeap, 0, aDirSrcLength + WILD_CARD_LEN + sizeof(L'\x00'))) != NULL) |
859 | { |
860 | StringCchCopyW(pName, sizeof(pName) / sizeof(pName[0]), dirSrc); |
861 | StringCchCatW (pName, sizeof(pName) / sizeof(pName[0]), WILD_CARD); |
862 | |
863 | retVal = TRUE; |
864 | hFindFile = FindFirstFileExW (pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0); |
865 | for (BOOL fFind = hFindFile != INVALID_HANDLE_VALUE; fFind; fFind = FindNextFileW (hFindFile, pFD)) |
866 | { |
867 | if ((pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'\0') |
868 | || (pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'.' && pFD->cFileName[2] == L'\0')) |
869 | { |
870 | continue; |
871 | } |
872 | |
873 | size_t aDirSrcLength2 = 0, aDirDstLength = 0, aFileNameLength = 0; |
874 | StringCchLengthW (dirSrc, sizeof(dirSrc) / sizeof(dirSrc[0]), &aDirSrcLength2); |
875 | StringCchLengthW (dirDst, sizeof(dirDst) / sizeof(dirDst[0]), &aDirDstLength); |
876 | StringCchLengthW (pFD->cFileName, sizeof(pFD->cFileName) / sizeof(pFD->cFileName[0]), &aFileNameLength); |
877 | if ((pFullNameSrc = (wchar_t* )HeapAlloc (hHeap, 0, aDirSrcLength2 + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL |
878 | || (pFullNameDst = (wchar_t* )HeapAlloc (hHeap, 0, aDirDstLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00'))) == NULL) |
879 | { |
880 | break; |
881 | } |
882 | |
883 | StringCchCopyW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), dirSrc); |
884 | StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), L"/"); |
885 | StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), pFD->cFileName); |
886 | |
887 | StringCchCopyW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), dirDst); |
888 | StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), L"/"); |
889 | StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), pFD->cFileName); |
890 | if ((pFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) |
891 | { |
892 | retVal = CopyDirectory (pFullNameSrc, pFullNameDst); |
893 | if (!retVal) |
894 | { |
895 | break; |
896 | } |
897 | } |
7fd59977 |
898 | else |
c0f08310 |
899 | { |
900 | retry: |
901 | #ifndef OCCT_UWP |
902 | retVal = CopyFileW (pFullNameSrc, pFullNameDst, FALSE); |
903 | #else |
904 | retVal = (CopyFile2 (pFullNameSrc, pFullNameDst, FALSE) == S_OK) ? TRUE : FALSE; |
905 | #endif |
906 | if (!retVal) |
907 | { |
908 | if (_response_dir_proc != NULL) |
909 | { |
910 | const DIR_RESPONSE response = _response_dir_proc (pFullNameSrc); |
911 | if (response == DIR_ABORT) |
912 | { |
913 | break; |
914 | } |
915 | else if (response == DIR_RETRY) |
916 | { |
917 | goto retry; |
918 | } |
919 | else if (response == DIR_IGNORE) |
920 | { |
921 | retVal = TRUE; |
922 | } |
923 | else |
924 | { |
925 | break; |
926 | } |
927 | } |
928 | } |
929 | else if (_copy_dir_proc != NULL) |
930 | { |
931 | _copy_dir_proc (pFullNameSrc, pFullNameDst); |
932 | } |
933 | } |
934 | |
935 | HeapFree (hHeap, 0, pFullNameDst); |
936 | HeapFree (hHeap, 0, pFullNameSrc); |
937 | pFullNameSrc = pFullNameDst = NULL; |
938 | } |
939 | } |
940 | } |
941 | |
942 | if (hFindFile != INVALID_HANDLE_VALUE) |
943 | { |
944 | FindClose (hFindFile); |
945 | } |
946 | |
947 | if (pFullNameSrc != NULL) |
948 | { |
949 | HeapFree (hHeap, 0, pFullNameSrc); |
950 | } |
951 | if (pFullNameDst != NULL) |
952 | { |
953 | HeapFree (hHeap, 0, pFullNameDst); |
954 | } |
955 | if (pName != NULL) |
956 | { |
957 | HeapFree (hHeap, 0, pName); |
958 | } |
959 | if (pFD != NULL) |
960 | { |
961 | HeapFree (hHeap, 0, pFD); |
962 | } |
963 | |
964 | return retVal; |
7fd59977 |
965 | } /* end CopyDirectory */ |
966 | /***/ |
967 | /******************************************************************************/ |
7fd59977 |
968 | /* Function : SetMoveDirectoryProc */ |
969 | /* Purpose : Sets callback procedure which is calling by the */ |
970 | /* 'MoveDirectory' after moving of each item in the */ |
971 | /* directory. To unregister this callback function supply NULL */ |
972 | /* pointer */ |
973 | /******************************************************************************/ |
974 | /***/ |
975 | void SetMoveDirectoryProc ( MOVE_DIR_PROC proc ) { |
976 | |
977 | _move_dir_proc = proc; |
978 | |
979 | } /* end SetMoveDirectoryProc */ |
980 | /***/ |
981 | /******************************************************************************/ |
982 | /* Function : SetCopyDirectoryProc */ |
983 | /* Purpose : Sets callback procedure which is calling by the */ |
984 | /* 'CopyDirectory' after copying of each item in the */ |
985 | /* directory. To unregister this callback function supply NULL */ |
986 | /* pointer */ |
987 | /******************************************************************************/ |
988 | /***/ |
989 | void SetCopyDirectoryProc ( COPY_DIR_PROC proc ) { |
990 | |
991 | _copy_dir_proc = proc; |
992 | |
993 | } /* end SetCopyDirectoryProc */ |
994 | /***/ |
995 | /******************************************************************************/ |
996 | /* Function : SetResponseDirectoryProc */ |
997 | /* Purpose : Sets callback procedure which is calling by the */ |
998 | /* directoy processing function if an error was occur. */ |
999 | /* The return value of that callback procedure determines */ |
1000 | /* behaviour of directoy processing functions in case of error. */ |
1001 | /* To unregister this callback function supply NULL pointer */ |
1002 | /******************************************************************************/ |
1003 | /***/ |
1004 | void SetResponseDirectoryProc ( RESPONSE_DIR_PROC proc ) { |
1005 | |
1006 | _response_dir_proc = proc; |
1007 | |
1008 | } /* end SetResponseDirectoryProc */ |
1009 | /***/ |
1010 | /******************************************************************************/ |
1011 | /******************************************************************************/ |
1012 | /******************************************************************************/ |
1013 | #endif |