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 | |
7fd59977 |
16 | #ifdef WNT |
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 | /***/ |
24 | #include <OSD_WNT_1.hxx> |
25 | |
d9ff84e8 |
26 | #include <wchar.h> |
7fd59977 |
27 | #include <stdlib.h> |
28 | /***/ |
29 | static void Init ( void ); |
30 | /***/ |
31 | static DWORD dwLevel; |
32 | /***/ |
33 | class Init_OSD_WNT { // provides initialization |
34 | |
35 | public: |
36 | |
37 | Init_OSD_WNT () { Init (); dwLevel = TlsAlloc (); } |
38 | |
39 | }; // end Init_OSD_WNT |
40 | |
41 | static Init_OSD_WNT initOsdWnt; |
42 | /***/ |
43 | static BOOL fInit = FALSE; |
44 | static PSID* predefinedSIDs; |
45 | static HANDLE hHeap; |
46 | /***/ |
7fd59977 |
47 | static MOVE_DIR_PROC _move_dir_proc; |
48 | static COPY_DIR_PROC _copy_dir_proc; |
49 | static RESPONSE_DIR_PROC _response_dir_proc; |
50 | /***/ |
51 | #define PREDEFINED_SIDs_COUNT 9 |
52 | #define UNIVERSAL_PREDEFINED_SIDs_COUNT 5 |
53 | /***/ |
54 | #define SID_INTERACTIVE 0 |
55 | #define SID_NETWORK 1 |
56 | #define SID_LOCAL 2 |
57 | #define SID_DIALUP 3 |
58 | #define SID_BATCH 4 |
59 | #define SID_CREATOR_OWNER 5 |
60 | #define SID_ADMIN 6 |
61 | #define SID_WORLD 7 |
62 | #define SID_NULL 8 |
63 | /***/ |
64 | /******************************************************************************/ |
65 | /* Function : AllocSD */ |
66 | /* Purpose : Allocates and initializes security identifier */ |
67 | /* Returns : Pointer to allocated SID on success, NULL otherwise */ |
68 | /* Warning : Allocated SID must be deallocated by 'FreeSD' function */ |
69 | /******************************************************************************/ |
70 | /***/ |
71 | PSECURITY_DESCRIPTOR AllocSD ( void ) { |
72 | |
73 | PSECURITY_DESCRIPTOR retVal = |
74 | ( PSECURITY_DESCRIPTOR )HeapAlloc ( |
75 | hHeap, 0, sizeof ( SECURITY_DESCRIPTOR ) |
76 | ); |
77 | |
78 | if ( retVal != NULL && |
79 | !InitializeSecurityDescriptor ( retVal, SECURITY_DESCRIPTOR_REVISION ) |
80 | ) { |
81 | |
82 | HeapFree ( hHeap, 0, ( PVOID )retVal ); |
83 | retVal = NULL; |
84 | |
85 | } /* end if */ |
86 | |
87 | return retVal; |
88 | |
89 | } /* end AllocSD */ |
90 | /***/ |
91 | /******************************************************************************/ |
92 | /* Function : FreeSD */ |
93 | /* Purpose : Deallocates security identifier which was allocated by the */ |
94 | /* 'AllocSD' function */ |
95 | /******************************************************************************/ |
96 | /***/ |
97 | void FreeSD ( PSECURITY_DESCRIPTOR pSD ) { |
98 | |
99 | BOOL fPresent; |
100 | BOOL fDaclDefaulted; |
101 | PACL pACL; |
102 | |
103 | if ( GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDaclDefaulted ) && |
104 | fPresent |
105 | ) |
106 | |
107 | HeapFree ( hHeap, 0, ( PVOID )pACL ); |
108 | |
109 | HeapFree ( hHeap, 0, ( PVOID )pSD ); |
110 | |
111 | } /* end FreeSD */ |
112 | /***/ |
113 | /******************************************************************************/ |
114 | /* Function : GetTokenInformationEx */ |
115 | /* Purpose : Allocates and fills out access token */ |
116 | /* Returns : Pointer to the access token on success, NULL otherwise */ |
117 | /* Warning : Allocated access token must be deallocated by */ |
118 | /* 'FreeTokenInformation' function */ |
119 | /******************************************************************************/ |
120 | /***/ |
121 | |
122 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
123 | #define __try |
124 | #define __finally |
125 | #define __leave return buffer |
126 | #endif |
127 | |
128 | LPVOID GetTokenInformationEx ( HANDLE hToken, TOKEN_INFORMATION_CLASS tic ) { |
129 | |
130 | DWORD errVal; |
131 | DWORD dwSize; |
132 | DWORD dwSizeNeeded = 0; |
133 | LPVOID buffer = NULL; |
134 | BOOL fOK = FALSE; |
135 | |
136 | __try { |
137 | |
138 | do { |
139 | |
140 | dwSize = dwSizeNeeded; |
141 | errVal = ERROR_SUCCESS; |
142 | |
143 | if ( !GetTokenInformation ( hToken, tic, buffer, dwSize, &dwSizeNeeded ) ) { |
144 | |
145 | if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER ) |
146 | |
147 | __leave; |
148 | |
149 | if ( ( buffer = HeapAlloc ( hHeap, 0, dwSizeNeeded ) ) == NULL ) |
150 | |
151 | __leave; |
152 | |
153 | } /* end if */ |
154 | |
155 | } while ( errVal != ERROR_SUCCESS ); |
156 | |
157 | fOK = TRUE; |
158 | |
159 | } /* end __try */ |
160 | |
161 | __finally { |
162 | |
163 | if ( !fOK && buffer != NULL ) { |
164 | |
165 | HeapFree ( hHeap, 0, buffer ); |
166 | buffer = NULL; |
167 | |
168 | } /* end if */ |
169 | |
170 | } /* end __finally */ |
171 | |
172 | #ifdef VAC |
173 | leave: ; // added for VisualAge |
174 | #endif |
175 | |
176 | return buffer; |
177 | |
178 | } /* end GetTokenInformationEx */ |
179 | |
180 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
181 | #undef __try |
182 | #undef __finally |
183 | #undef __leave |
184 | #endif |
185 | |
186 | /***/ |
187 | /******************************************************************************/ |
188 | /* Function : FreeTokenInformation */ |
189 | /* Purpose : Deallocates access token which was allocated by the */ |
190 | /* 'GetTokenInformationEx' function */ |
191 | /******************************************************************************/ |
192 | /***/ |
193 | void FreeTokenInformation ( LPVOID lpvTkInfo ) { |
194 | |
195 | HeapFree ( hHeap, 0, lpvTkInfo ); |
196 | |
197 | } /* end FreeTokenInformation */ |
198 | /***/ |
199 | /******************************************************************************/ |
200 | /* Function : Init */ |
201 | /* Purpose : Allocates and initializes predefined security identifiers */ |
202 | /* Warning : Generates 'STATUS_NO_MEMORY' software exception if there are */ |
203 | /* insufficient of memory. This exception can be caught by using */ |
204 | /* software exception handling ( SEH ) mechanism */ |
205 | /* ( __try / __except ) */ |
206 | /******************************************************************************/ |
207 | /***/ |
208 | static void Init ( void ) { |
209 | |
210 | SID_IDENTIFIER_AUTHORITY sidIDAnull = SECURITY_NULL_SID_AUTHORITY; |
211 | SID_IDENTIFIER_AUTHORITY sidIDAworld = SECURITY_WORLD_SID_AUTHORITY; |
212 | SID_IDENTIFIER_AUTHORITY sidIDANT = SECURITY_NT_AUTHORITY; |
213 | SID_IDENTIFIER_AUTHORITY sidIDAlocal = SECURITY_LOCAL_SID_AUTHORITY; |
214 | SID_IDENTIFIER_AUTHORITY sidIDAcreator = SECURITY_CREATOR_SID_AUTHORITY; |
215 | |
216 | if ( !fInit ) { |
217 | |
218 | predefinedSIDs = ( PSID* )HeapAlloc ( |
219 | hHeap = GetProcessHeap (), |
220 | HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, |
221 | PREDEFINED_SIDs_COUNT * sizeof ( PSID* ) |
222 | ); |
223 | |
224 | AllocateAndInitializeSid ( |
225 | &sidIDANT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, |
226 | 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_ADMIN ] |
227 | ); |
228 | |
229 | AllocateAndInitializeSid ( |
230 | &sidIDAworld, 1, SECURITY_WORLD_RID, |
231 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_WORLD ] |
232 | ); |
233 | |
234 | AllocateAndInitializeSid ( |
235 | &sidIDANT, 1, SECURITY_INTERACTIVE_RID, |
236 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_INTERACTIVE ] |
237 | ); |
238 | |
239 | AllocateAndInitializeSid ( |
240 | &sidIDANT, 1, SECURITY_NETWORK_RID, |
241 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NETWORK ] |
242 | ); |
243 | |
244 | AllocateAndInitializeSid ( |
245 | &sidIDAlocal, 1, SECURITY_LOCAL_RID, |
246 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_LOCAL ] |
247 | ); |
248 | |
249 | AllocateAndInitializeSid ( |
250 | &sidIDANT, 1, SECURITY_DIALUP_RID, |
251 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_DIALUP ] |
252 | ); |
253 | |
254 | AllocateAndInitializeSid ( |
255 | &sidIDANT, 1, SECURITY_BATCH_RID, |
256 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_BATCH ] |
257 | ); |
258 | |
259 | AllocateAndInitializeSid ( |
260 | &sidIDAcreator, 1, SECURITY_CREATOR_OWNER_RID, |
261 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_CREATOR_OWNER ] |
262 | ); |
263 | |
264 | AllocateAndInitializeSid ( |
265 | &sidIDAnull, 1, SECURITY_NULL_RID, |
266 | 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NULL ] |
267 | ); |
268 | |
269 | fInit = TRUE; |
270 | |
271 | } /* end if */ |
272 | |
273 | } /* end init */ |
274 | /***/ |
275 | /******************************************************************************/ |
276 | /* Function : PredefinedSid */ |
277 | /* Purpose : Checks whether specified SID predefined or not */ |
278 | /* Returns : TRUE if specified SID is predefined, FALSE otherwise */ |
279 | /******************************************************************************/ |
280 | /***/ |
281 | BOOL PredefinedSid ( PSID pSID ) { |
282 | |
283 | int i; |
284 | |
285 | for ( i = 0; i < PREDEFINED_SIDs_COUNT; ++i ) |
286 | |
287 | if ( EqualSid ( pSID, predefinedSIDs[ i ] ) ) |
288 | |
289 | return TRUE; |
290 | |
291 | return FALSE; |
292 | |
293 | } /* end PredefinedSid */ |
294 | /***/ |
295 | /******************************************************************************/ |
296 | /* Function : NtPredefinedSid */ |
297 | /* Purpose : Checks whether specified SID universal or not */ |
298 | /* Returns : TRUE if specified SID is NOT universal, FALSE otherwise */ |
299 | /******************************************************************************/ |
300 | /***/ |
301 | BOOL NtPredefinedSid ( PSID pSID ) { |
302 | |
303 | int i; |
304 | PSID_IDENTIFIER_AUTHORITY pTestIDA; |
305 | SID_IDENTIFIER_AUTHORITY ntIDA = SECURITY_NT_AUTHORITY; |
306 | PDWORD pdwTestSA; |
307 | |
308 | for ( i = 0; i < UNIVERSAL_PREDEFINED_SIDs_COUNT; ++i ) |
309 | |
310 | if ( EqualSid ( pSID, predefinedSIDs[ i ] ) ) |
311 | |
312 | return TRUE; |
313 | |
314 | pTestIDA = GetSidIdentifierAuthority ( pSID ); |
315 | |
316 | if ( memcmp ( pTestIDA, &ntIDA, sizeof ( SID_IDENTIFIER_AUTHORITY ) ) == 0 ) { |
317 | |
318 | pdwTestSA = GetSidSubAuthority ( pSID, 0 ); |
319 | |
320 | if ( *pdwTestSA == SECURITY_LOGON_IDS_RID ) |
321 | |
322 | return TRUE; |
323 | |
324 | } /* end if */ |
325 | |
326 | return FALSE; |
327 | |
328 | } /* end NtPredefinedSid */ |
329 | /***/ |
330 | /******************************************************************************/ |
331 | /* Function : AdminSid */ |
332 | /* Purpose : Returns SID of the administrative user account */ |
333 | /******************************************************************************/ |
334 | /***/ |
335 | PSID AdminSid ( void ) { |
336 | |
337 | return predefinedSIDs[ SID_ADMIN ]; |
338 | |
339 | } /* end AdminSid */ |
340 | /***/ |
341 | /******************************************************************************/ |
342 | /* Function : WorldSid */ |
343 | /* Purpose : Returns SID of group that includes all users */ |
344 | /******************************************************************************/ |
345 | /***/ |
346 | PSID WorldSid ( void ) { |
347 | |
348 | return predefinedSIDs[ SID_WORLD ]; |
349 | |
350 | } /* end WorldSid */ |
351 | /***/ |
352 | /******************************************************************************/ |
353 | /* Function : InteractiveSid */ |
354 | /* Purpose : Returns SID of group that includes all users logged on for */ |
355 | /* interactive operation */ |
356 | /******************************************************************************/ |
357 | /***/ |
358 | PSID InteractiveSid ( void ) { |
359 | |
360 | return predefinedSIDs[ SID_INTERACTIVE ]; |
361 | |
362 | } /* end InteractiveSID */ |
363 | /***/ |
364 | /******************************************************************************/ |
365 | /* Function : NetworkSid */ |
366 | /* Purpose : Returns SID of group that includes all users logged on across */ |
367 | /* a network */ |
368 | /******************************************************************************/ |
369 | /***/ |
370 | PSID NetworkSid ( void ) { |
371 | |
372 | return predefinedSIDs[ SID_NETWORK ]; |
373 | |
374 | } /* end NetworkSid */ |
375 | /***/ |
376 | /******************************************************************************/ |
377 | /* Function : LocalSid */ |
378 | /* Purpose : Returns SID of group that includes all users logged on locally*/ |
379 | /******************************************************************************/ |
380 | /***/ |
381 | PSID LocalSid ( void ) { |
382 | |
383 | return predefinedSIDs[ SID_LOCAL ]; |
384 | |
385 | } /* end LocalSid */ |
386 | /***/ |
387 | /******************************************************************************/ |
388 | /* Function : DialupSid */ |
389 | /* Purpose : Returns SID of group that includes all users logged on to */ |
390 | /* terminals using a dialup modem */ |
391 | /******************************************************************************/ |
392 | /***/ |
393 | PSID DialupSid ( void ) { |
394 | |
395 | return predefinedSIDs[ SID_DIALUP ]; |
396 | |
397 | } /* end DialupSid */ |
398 | /***/ |
399 | /******************************************************************************/ |
400 | /* Function : BatchSid */ |
401 | /* Purpose : Returns SID of group that includes all users logged on using */ |
402 | /* a batch queue facility */ |
403 | /******************************************************************************/ |
404 | /***/ |
405 | PSID BatchSid ( void ) { |
406 | |
407 | return predefinedSIDs[ SID_BATCH ]; |
408 | |
409 | } /* end BatchSid */ |
410 | /***/ |
411 | /******************************************************************************/ |
412 | /* Function : CreatorOwnerSid */ |
413 | /* Purpose : Returns SID of 'CREATOR OWNER' special group */ |
414 | /******************************************************************************/ |
415 | /***/ |
416 | PSID CreatorOwnerSid ( void ) { |
417 | |
418 | return predefinedSIDs[ SID_CREATOR_OWNER ]; |
419 | |
420 | } /* end CreatorOwnerSid */ |
421 | /***/ |
422 | /******************************************************************************/ |
423 | /* Function : NullSid */ |
424 | /* Purpose : Returns null SID */ |
425 | /******************************************************************************/ |
426 | /***/ |
427 | PSID NullSid ( void ) { |
428 | |
429 | return predefinedSIDs[ SID_NULL ]; |
430 | |
431 | } /* end NullSid */ |
432 | /***/ |
433 | /******************************************************************************/ |
434 | /* Function : GetFileSecurityEx */ |
435 | /* Purpose : Allocates a security descriptor and fills it out by security */ |
436 | /* information which belongs to the specified file */ |
437 | /* Returns : Pointer to the allocated security descriptor on success */ |
438 | /* NULL otherwise */ |
439 | /* Warning : Allocated security descriptor must be deallocated by */ |
440 | /* 'FreeFileSecurity' function */ |
441 | /******************************************************************************/ |
442 | /***/ |
443 | |
444 | |
445 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
446 | #define __try |
447 | #define __finally |
448 | #define __leave return retVal |
449 | #endif |
450 | |
d9ff84e8 |
451 | PSECURITY_DESCRIPTOR GetFileSecurityEx ( LPCWSTR fileName, SECURITY_INFORMATION si ) { |
7fd59977 |
452 | |
453 | DWORD errVal; |
454 | DWORD dwSize; |
455 | DWORD dwSizeNeeded = 0; |
456 | PSECURITY_DESCRIPTOR retVal = NULL; |
457 | BOOL fOK = FALSE; |
458 | |
459 | __try { |
460 | |
461 | do { |
462 | |
463 | dwSize = dwSizeNeeded; |
464 | errVal = ERROR_SUCCESS; |
465 | |
d9ff84e8 |
466 | if ( !GetFileSecurityW ( |
7fd59977 |
467 | fileName, si, |
468 | retVal, dwSize, &dwSizeNeeded |
469 | ) |
470 | ) { |
471 | |
472 | if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER ) __leave; |
473 | |
474 | if ( ( retVal = ( PSECURITY_DESCRIPTOR )HeapAlloc ( hHeap, 0, dwSizeNeeded ) |
475 | ) == NULL |
476 | ) __leave; |
477 | |
478 | } /* end if */ |
479 | |
480 | } while ( errVal != ERROR_SUCCESS ); |
481 | |
482 | fOK = TRUE; |
483 | |
484 | } /* end __try */ |
485 | |
486 | __finally { |
487 | |
488 | if ( !fOK && retVal != NULL ) { |
489 | |
490 | HeapFree ( hHeap, 0, retVal ); |
491 | retVal = NULL; |
492 | |
493 | } /* end if */ |
494 | |
495 | } /* end __finally */ |
496 | |
497 | #ifdef VAC |
498 | leave: ; // added for VisualAge |
499 | #endif |
500 | |
501 | return retVal; |
502 | |
503 | } /* end GetFileSecurityEx */ |
504 | |
505 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
506 | #undef __try |
507 | #undef __finally |
508 | #undef __leave |
509 | #endif |
510 | |
511 | /***/ |
512 | /******************************************************************************/ |
513 | /* Function : FreeFileSecurity */ |
514 | /* Purpose : Deallocates security descriptor which was allocated by the */ |
515 | /* 'GetFileSecurityEx' function */ |
516 | /******************************************************************************/ |
517 | /***/ |
518 | void FreeFileSecurity ( PSECURITY_DESCRIPTOR pSD ) { |
519 | |
520 | HeapFree ( hHeap, 0, ( LPVOID )pSD ); |
521 | |
522 | } /* end FreeFileSecurity */ |
523 | /***/ |
524 | /******************************************************************************/ |
525 | /* Function : LookupAccountSidEx */ |
526 | /* Purpose : Looking for account corresponding to the given SID and returns*/ |
527 | /* a name of that account on success */ |
528 | /* Returns : TRUE if account was found in the security database */ |
529 | /* FALSE otherwise */ |
530 | /* Warning : If account was found then this function allocates memory */ |
531 | /* needed to hold the name of that account and the name of the */ |
532 | /* domain to which this account belongs. To free that memoty */ |
533 | /* use 'FreeAccountNames' function */ |
534 | /******************************************************************************/ |
535 | /***/ |
536 | |
537 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
538 | #define __try |
539 | #define __finally |
540 | #define __leave return retVal |
541 | #endif |
542 | |
d9ff84e8 |
543 | BOOL LookupAccountSidEx ( PSID pSID, LPWSTR* name, LPWSTR* domain ) { |
7fd59977 |
544 | |
545 | DWORD errVal; |
546 | DWORD dwSizeName = 0; |
547 | DWORD dwSizeDomain = 0; |
548 | BOOL retVal = FALSE; |
549 | SID_NAME_USE eUse; |
550 | |
551 | __try { |
552 | |
553 | do { |
554 | |
555 | errVal = ERROR_SUCCESS; |
556 | |
d9ff84e8 |
557 | if ( !LookupAccountSidW ( |
7fd59977 |
558 | NULL, pSID, *name, &dwSizeName, *domain, &dwSizeDomain, &eUse |
559 | ) |
560 | ) { |
561 | |
562 | if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER ) __leave; |
563 | |
d9ff84e8 |
564 | if ( ( *name = ( LPWSTR )HeapAlloc ( hHeap, 0, dwSizeName ) ) == NULL || |
565 | ( *domain = ( LPWSTR )HeapAlloc ( hHeap, 0, dwSizeDomain ) ) == NULL |
7fd59977 |
566 | ) __leave; |
567 | |
568 | } /* end if */ |
569 | |
570 | } while ( errVal != ERROR_SUCCESS ); |
571 | |
572 | retVal = TRUE; |
573 | |
574 | } /* end __try */ |
575 | |
576 | __finally { |
577 | |
578 | if ( !retVal ) { |
579 | |
580 | if ( *name == NULL ) HeapFree ( hHeap, 0, *name ); |
581 | if ( *domain == NULL ) HeapFree ( hHeap, 0, *domain ); |
582 | |
583 | } /* end if */ |
584 | |
585 | } /* end __finally */ |
586 | |
587 | #ifdef VAC |
588 | leave: ; // added for VisualAge |
589 | #endif |
590 | |
591 | return retVal; |
592 | |
593 | } /* end LookupAccountSidEx */ |
594 | |
595 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
596 | #undef __try |
597 | #undef __finally |
598 | #undef __leave |
599 | #endif |
600 | |
601 | /***/ |
602 | /******************************************************************************/ |
603 | /* Function : FreeAccountNames */ |
604 | /* Purpose : Deallocates memory which was allocated by the */ |
605 | /* 'LookupAccountSidEx' function */ |
606 | /******************************************************************************/ |
607 | /***/ |
d9ff84e8 |
608 | void FreeAccountNames ( LPWSTR lpszName, LPWSTR lpszDomain ) { |
7fd59977 |
609 | |
610 | HeapFree ( hHeap, 0, ( PVOID )lpszDomain ); |
611 | HeapFree ( hHeap, 0, ( PVOID )lpszName ); |
612 | |
613 | } /* end FreeAccountNames */ |
614 | /***/ |
615 | /******************************************************************************/ |
616 | /* Function : GetSecurityDescriptorOwnerEx */ |
617 | /* Purpose : Returns owner SID in the specified security descriptor. */ |
618 | /* If specified security descriptor does not have an owner field */ |
619 | /* then returns NULL */ |
620 | /******************************************************************************/ |
621 | /***/ |
622 | PSID GetSecurityDescriptorOwnerEx ( PSECURITY_DESCRIPTOR pSD ) { |
623 | |
624 | BOOL bDummy; |
625 | PSID retVal; |
626 | |
627 | if ( !GetSecurityDescriptorOwner ( pSD, &retVal, &bDummy ) ) |
628 | |
629 | retVal = NULL; |
630 | |
631 | return retVal; |
632 | |
633 | } /* end GetSecurityDescriptorOwnerEx */ |
634 | /***/ |
635 | /******************************************************************************/ |
636 | /* Function : GetSecurityDescriptorGroupEx */ |
637 | /* Purpose : Returns primary group SID in the specified security */ |
638 | /* descriptor. If specified security descriptor does not have a */ |
639 | /* primary group field then returns NULL */ |
640 | /******************************************************************************/ |
641 | /***/ |
642 | PSID GetSecurityDescriptorGroupEx ( PSECURITY_DESCRIPTOR pSD ) { |
643 | |
644 | BOOL bDummy; |
645 | PSID retVal; |
646 | |
647 | if ( !GetSecurityDescriptorGroup ( pSD, &retVal, &bDummy ) ) |
648 | |
649 | retVal = NULL; |
650 | |
651 | return retVal; |
652 | |
653 | } /* end GetSecurityDescriptorGroupEx */ |
654 | /***/ |
655 | /******************************************************************************/ |
656 | /* Function : GetSecurityDescriptorDaclEx */ |
657 | /* Purpose : Returns a pointer to the discretionary access-control list in */ |
658 | /* the specified security descriptor. If specified security */ |
659 | /* descriptor does not have a discretionary access-control list */ |
660 | /* then returns NULL */ |
661 | /******************************************************************************/ |
662 | /***/ |
663 | PACL GetSecurityDescriptorDaclEx ( PSECURITY_DESCRIPTOR pSD ) { |
664 | |
665 | PACL retVal; |
666 | BOOL bDummy; |
667 | BOOL fPresent; |
668 | |
669 | if ( !GetSecurityDescriptorDacl ( pSD, &fPresent, &retVal, &bDummy ) || |
670 | !fPresent |
671 | ) |
672 | |
673 | retVal = NULL; |
674 | |
675 | return retVal; |
676 | |
677 | } /* end GetSecurityDescriptorDaclEx */ |
678 | /***/ |
679 | /******************************************************************************/ |
680 | /* Function : CreateAcl */ |
681 | /* Purpose : Allocates and initializes access-control list */ |
682 | /* Returns : Pointer to the allocated and initialized ACL on success, */ |
683 | /* NULL otherwise */ |
684 | /* Warning : Allocated ACL must be deallocated by 'FreeAcl' function */ |
685 | /******************************************************************************/ |
686 | /***/ |
687 | PACL CreateAcl ( DWORD dwAclSize ) { |
688 | |
689 | PACL retVal; |
690 | |
691 | retVal = ( PACL )HeapAlloc ( hHeap, 0, dwAclSize ); |
692 | |
693 | if ( retVal != NULL ) |
694 | |
695 | InitializeAcl ( retVal, dwAclSize, ACL_REVISION ); |
696 | |
697 | return retVal; |
698 | |
699 | } /* end CreateAcl */ |
700 | /***/ |
701 | /******************************************************************************/ |
702 | /* Function : FreeAcl */ |
703 | /* Purpose : Deallocates access-control list which was allocated by the */ |
704 | /* 'CreateAcl' function */ |
705 | /******************************************************************************/ |
706 | /***/ |
707 | void FreeAcl ( PACL pACL ) { |
708 | |
709 | HeapFree ( hHeap, 0, ( PVOID )pACL ); |
710 | |
711 | } /* end FreeAcl */ |
712 | /***/ |
713 | /******************************************************************************/ |
714 | /* Function : CopySidEx */ |
715 | /* Purpose : Makes a copy of the SID */ |
716 | /* Returns : Pointer to the copy of the specified SID on success, */ |
717 | /* NULL otherwise */ |
718 | /* Warning : Allocated SID must be deallocated by 'FreeSidEx' function */ |
719 | /******************************************************************************/ |
720 | /***/ |
721 | PSID CopySidEx ( PSID pSIDsrc ) { |
722 | |
723 | DWORD dwLen; |
724 | PSID retVal; |
725 | |
726 | dwLen = GetLengthSid ( pSIDsrc ); |
727 | retVal = ( PSID )HeapAlloc ( hHeap, 0, dwLen ); |
728 | |
729 | if ( retVal != NULL ) |
730 | |
731 | CopySid ( dwLen, retVal, pSIDsrc ); |
732 | |
733 | return retVal; |
734 | |
735 | } /* end CopySidEx */ |
736 | /***/ |
737 | /******************************************************************************/ |
738 | /* Function : FreeSidEx */ |
739 | /* Purpose : Deallocates SID which was allocated by the 'CopySidEx' */ |
740 | /* function */ |
741 | /******************************************************************************/ |
742 | /***/ |
743 | void FreeSidEx ( PSID pSID ) { |
744 | |
745 | HeapFree ( hHeap, 0, pSID ); |
746 | |
747 | } /* end FreeSidEx */ |
748 | /***/ |
749 | /******************************************************************************/ |
750 | /* Function : AllocGroupSid */ |
751 | /* Purpose : Allocates a structure which holds SIDs of groups which are */ |
752 | /* not predefined. These SIDs is taking from the DACL of the */ |
753 | /* specified security descriptor */ |
754 | /* Returns : Pointer the allocated structure on success, */ |
755 | /* NULL otherwise */ |
756 | /* Warning : Allocated structure must be deallocated by 'FreeGroupSid' */ |
757 | /* function */ |
758 | /******************************************************************************/ |
759 | /***/ |
760 | PGROUP_SID AllocGroupSid ( PSECURITY_DESCRIPTOR pSD ) { |
761 | |
762 | int i; |
763 | PGROUP_SID retVal = NULL; |
764 | PSID* pSID = NULL; |
765 | DWORD dwLen; |
766 | DWORD dwCount = 0; |
767 | LPVOID pACE; |
768 | PACL pACL; |
769 | PSID pSIDowner; |
770 | PSID pSIDadmin; |
771 | PSID pSIDworld; |
772 | BOOL fPresent; |
773 | BOOL fDefaulted; |
774 | |
775 | if ( GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDefaulted ) && |
776 | fPresent && |
777 | GetSecurityDescriptorOwner ( pSD, &pSIDowner, &fDefaulted ) && |
778 | pSIDowner != NULL && |
779 | ( retVal = ( PGROUP_SID )HeapAlloc ( hHeap, 0, sizeof ( GROUP_SID ) ) ) != |
780 | NULL |
781 | ) { |
782 | |
783 | pSIDadmin = AdminSid (); |
784 | pSIDworld = WorldSid (); |
785 | |
786 | for ( i = 0; i < ( int )pACL -> AceCount; ++i ) |
787 | if ( GetAce ( pACL, i, &pACE ) && |
788 | !EqualSid ( pSIDadmin, GET_SID( pACE ) ) && |
789 | !EqualSid ( pSIDworld, GET_SID( pACE ) ) && |
790 | !EqualSid ( pSIDowner, GET_SID( pACE ) ) ) |
791 | ++dwCount; |
792 | |
793 | pSID = ( PSID* )HeapAlloc ( hHeap, 0, dwCount * sizeof ( PSID ) ); |
794 | dwCount = 0; |
795 | |
796 | if ( pSID != NULL ) { |
797 | |
798 | for ( i = 0; i < ( int )pACL -> AceCount; ++i ) |
799 | |
800 | if ( GetAce ( pACL, i, &pACE ) && |
801 | !EqualSid ( pSIDadmin, GET_SID( pACE ) ) && |
802 | !EqualSid ( pSIDworld, GET_SID( pACE ) ) && |
803 | !EqualSid ( pSIDowner, GET_SID( pACE ) ) |
804 | ) { |
805 | |
806 | pSID[ dwCount ] = ( PSID )HeapAlloc ( |
807 | hHeap, 0, dwLen = GetLengthSid ( GET_SID( pACE ) ) |
808 | ); |
809 | |
810 | if ( pSID[ dwCount ] != NULL ) |
811 | |
812 | CopySid ( dwLen, pSID[ dwCount++ ], GET_SID( pACE ) ); |
813 | |
814 | } /* end if */ |
815 | |
816 | } /* end if */ |
817 | |
818 | retVal -> nCount = dwCount; |
819 | retVal -> pSID = pSID; |
820 | |
821 | } /* end if */ |
822 | |
823 | return retVal; |
824 | |
825 | } /* end AllocGroupSid */ |
826 | /***/ |
827 | /******************************************************************************/ |
828 | /* Function : FreeGroupSid */ |
829 | /* Purpose : Deallocates a structure which was allocated by the */ |
830 | /* 'AllocGroupSid' function */ |
831 | /******************************************************************************/ |
832 | /***/ |
833 | void FreeGroupSid ( PGROUP_SID pGSID ) { |
834 | |
835 | int i; |
836 | |
837 | for ( i = 0; i < ( int )pGSID -> nCount; ++i ) |
838 | |
839 | HeapFree ( hHeap, 0, pGSID -> pSID[ i ] ); |
840 | |
841 | HeapFree ( hHeap, 0, pGSID -> pSID ); |
842 | HeapFree ( hHeap, 0, pGSID ); |
843 | |
844 | } /* end FreeGroupSid */ |
845 | /***/ |
846 | /******************************************************************************/ |
847 | /* Function : AllocAccessAllowedAce */ |
848 | /* Purpose : Allocates and initializes access-control entry */ |
849 | /* Returns : Pointer to the ACE on success, NULL othrwise */ |
850 | /* Warning : Allocated ACE must be deallocated by the 'FreeAce' function */ |
851 | /******************************************************************************/ |
852 | /***/ |
853 | PVOID AllocAccessAllowedAce ( DWORD dwMask, BYTE flags, PSID pSID ) { |
854 | |
855 | PFILE_ACE retVal; |
856 | WORD wSize; |
857 | |
858 | wSize = (WORD)( sizeof ( ACE_HEADER ) + sizeof ( DWORD ) + GetLengthSid ( pSID ) ); |
859 | |
860 | retVal = ( PFILE_ACE )HeapAlloc ( hHeap, 0, wSize ); |
861 | |
862 | if ( retVal != NULL ) { |
863 | |
864 | retVal -> header.AceType = ACCESS_ALLOWED_ACE_TYPE; |
865 | retVal -> header.AceFlags = flags; |
866 | retVal -> header.AceSize = wSize; |
867 | |
868 | retVal -> dwMask = dwMask; |
869 | |
870 | CopySid ( GetLengthSid ( pSID ), &retVal -> pSID, pSID ); |
871 | |
872 | } /* end if */ |
873 | |
874 | return retVal; |
875 | |
876 | } /* end AllocAccessAllowedAce */ |
877 | /***/ |
878 | /******************************************************************************/ |
879 | /* Function : FreeAce */ |
880 | /* Purpose : Deallocates an ACE which was allocated by the */ |
881 | /* 'AllocAccessAllowedAce ' function */ |
882 | /******************************************************************************/ |
883 | /***/ |
884 | void FreeAce ( PVOID pACE ) { |
885 | |
886 | HeapFree ( hHeap, 0, pACE ); |
887 | |
888 | } /* end FreeAce */ |
889 | |
d9ff84e8 |
890 | #define WILD_CARD L"/*.*" |
7fd59977 |
891 | #define WILD_CARD_LEN ( sizeof ( WILD_CARD ) ) |
892 | |
7fd59977 |
893 | /***/ |
894 | /******************************************************************************/ |
895 | /* Function : MoveDirectory */ |
896 | /* Purpose : Moves specified directory tree to the new location */ |
897 | /* Returns : TRUE on success, FALSE otherwise */ |
898 | /******************************************************************************/ |
899 | /***/ |
d9ff84e8 |
900 | BOOL MoveDirectory ( LPCWSTR oldDir, LPCWSTR newDir ) { |
7fd59977 |
901 | |
d9ff84e8 |
902 | PWIN32_FIND_DATAW pFD; |
903 | LPWSTR pName; |
904 | LPWSTR pFullNameSrc; |
905 | LPWSTR pFullNameDst; |
906 | LPWSTR driveSrc, driveDst; |
907 | LPWSTR pathSrc, pathDst; |
908 | HANDLE hFindFile; |
909 | BOOL fFind; |
910 | BOOL retVal = FALSE; |
911 | DIR_RESPONSE response; |
912 | DWORD level; |
7fd59977 |
913 | |
914 | if ( ( level = ( DWORD )TlsGetValue ( dwLevel ) ) == NULL ) { |
915 | |
916 | ++level; |
917 | TlsSetValue ( dwLevel, ( LPVOID )level ); |
918 | |
919 | fFind = FALSE; |
920 | driveSrc = driveDst = pathSrc = pathDst = NULL; |
921 | |
d9ff84e8 |
922 | if ( ( driveSrc = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DRIVE * sizeof(WCHAR) ) ) != NULL && |
923 | ( driveDst = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DRIVE * sizeof(WCHAR) ) ) != NULL && |
924 | ( pathSrc = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DIR * sizeof(WCHAR) ) ) != NULL && |
925 | ( pathDst = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DIR * sizeof(WCHAR) ) ) != NULL |
7fd59977 |
926 | ) { |
927 | |
d9ff84e8 |
928 | _wsplitpath ( oldDir, driveSrc, pathSrc, NULL, NULL ); |
929 | _wsplitpath ( newDir, driveDst, pathDst, NULL, NULL ); |
7fd59977 |
930 | |
d9ff84e8 |
931 | if ( wcscmp ( driveSrc, driveDst ) == 0 && |
932 | wcscmp ( pathSrc, pathDst ) == 0 |
7fd59977 |
933 | ) { |
934 | retry: |
d9ff84e8 |
935 | retVal = MoveFileExW ( |
7fd59977 |
936 | oldDir, newDir, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED |
937 | ); |
938 | fFind = TRUE; |
939 | |
940 | if ( !retVal ) { |
941 | |
942 | if ( _response_dir_proc != NULL ) { |
943 | |
944 | response = ( *_response_dir_proc ) ( oldDir ); |
945 | |
946 | if ( response == DIR_RETRY ) |
947 | |
948 | goto retry; |
949 | |
950 | else if ( response == DIR_IGNORE ) |
951 | |
952 | retVal = TRUE; |
953 | |
954 | } /* end if */ |
955 | |
956 | } else if ( _move_dir_proc != NULL ) |
957 | |
958 | ( *_move_dir_proc ) ( oldDir, newDir ); |
959 | |
960 | } /* end if */ |
961 | |
962 | } /* end if */ |
963 | |
964 | if ( pathDst != NULL ) HeapFree ( hHeap, 0, pathDst ); |
965 | if ( pathSrc != NULL ) HeapFree ( hHeap, 0, pathSrc ); |
966 | if ( driveDst != NULL ) HeapFree ( hHeap, 0, driveDst ); |
967 | if ( driveSrc != NULL ) HeapFree ( hHeap, 0, driveSrc ); |
968 | |
969 | if ( fFind ) { |
970 | |
971 | --level; |
972 | TlsSetValue ( dwLevel, ( LPVOID )level ); |
973 | return retVal; |
974 | |
975 | } // end if |
976 | |
977 | } else { |
978 | |
979 | ++level; |
980 | TlsSetValue ( dwLevel, ( LPVOID )level ); |
981 | |
982 | } // end else |
983 | |
984 | pFD = NULL; |
985 | pName = NULL; |
986 | pFullNameSrc = pFullNameDst = NULL; |
987 | hFindFile = INVALID_HANDLE_VALUE; |
988 | retVal = FALSE; |
989 | |
d9ff84e8 |
990 | retVal = CreateDirectoryW ( newDir, NULL ); |
7fd59977 |
991 | |
992 | if ( retVal || ( !retVal && GetLastError () == ERROR_ALREADY_EXISTS ) ) { |
993 | |
d9ff84e8 |
994 | if ( ( pFD = ( PWIN32_FIND_DATAW )HeapAlloc ( |
995 | hHeap, 0, sizeof ( WIN32_FIND_DATAW ) |
7fd59977 |
996 | ) |
997 | ) != NULL && |
d9ff84e8 |
998 | ( pName = ( LPWSTR )HeapAlloc ( |
999 | hHeap, 0, lstrlenW ( oldDir ) + WILD_CARD_LEN + |
1000 | sizeof ( L'\x00' ) |
7fd59977 |
1001 | ) |
1002 | ) != NULL |
1003 | ) { |
1004 | |
d9ff84e8 |
1005 | lstrcpyW ( pName, oldDir ); |
1006 | lstrcatW ( pName, WILD_CARD ); |
7fd59977 |
1007 | |
1008 | retVal = TRUE; |
d9ff84e8 |
1009 | fFind = ( hFindFile = FindFirstFileW ( pName, pFD ) ) != INVALID_HANDLE_VALUE; |
7fd59977 |
1010 | |
1011 | while ( fFind ) { |
1012 | |
d9ff84e8 |
1013 | if ( pFD -> cFileName[ 0 ] != L'.' || |
1014 | pFD -> cFileName[ 0 ] != L'.' && |
1015 | pFD -> cFileName[ 1 ] != L'.' |
7fd59977 |
1016 | ) { |
1017 | |
d9ff84e8 |
1018 | if ( ( pFullNameSrc = ( LPWSTR )HeapAlloc ( |
7fd59977 |
1019 | hHeap, 0, |
d9ff84e8 |
1020 | lstrlenW ( oldDir ) + lstrlenW ( pFD -> cFileName ) + |
1021 | sizeof ( L'/' ) + sizeof ( L'\x00' ) |
7fd59977 |
1022 | ) |
1023 | ) == NULL || |
d9ff84e8 |
1024 | ( pFullNameDst = ( LPWSTR )HeapAlloc ( |
7fd59977 |
1025 | hHeap, 0, |
d9ff84e8 |
1026 | lstrlenW ( newDir ) + lstrlenW ( pFD -> cFileName ) + |
1027 | sizeof ( L'/' ) + sizeof ( L'\x00' ) |
7fd59977 |
1028 | ) |
1029 | ) == NULL |
1030 | ) break; |
1031 | |
d9ff84e8 |
1032 | lstrcpyW ( pFullNameSrc, oldDir ); |
1033 | lstrcatW ( pFullNameSrc, L"/" ); |
1034 | lstrcatW ( pFullNameSrc, pFD -> cFileName ); |
7fd59977 |
1035 | |
d9ff84e8 |
1036 | lstrcpyW ( pFullNameDst, newDir ); |
1037 | lstrcatW ( pFullNameDst, L"/" ); |
1038 | lstrcatW ( pFullNameDst, pFD -> cFileName ); |
7fd59977 |
1039 | |
1040 | if ( pFD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { |
1041 | |
302f96fb |
1042 | retVal = MoveDirectory ( pFullNameSrc, pFullNameDst ); |
1043 | if (!retVal) break; |
7fd59977 |
1044 | |
1045 | } else { |
1046 | retry_1: |
d9ff84e8 |
1047 | retVal = MoveFileExW (pFullNameSrc, pFullNameDst, |
1048 | MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); |
302f96fb |
1049 | if (! retVal) { |
7fd59977 |
1050 | |
1051 | if ( _response_dir_proc != NULL ) { |
1052 | |
1053 | response = ( *_response_dir_proc ) ( pFullNameSrc ); |
1054 | |
1055 | if ( response == DIR_ABORT ) |
1056 | |
1057 | break; |
1058 | |
1059 | else if ( response == DIR_RETRY ) |
1060 | |
1061 | goto retry_1; |
1062 | |
1063 | else if ( response == DIR_IGNORE ) |
1064 | |
1065 | retVal = TRUE; |
1066 | |
1067 | else |
1068 | |
1069 | break; |
1070 | |
1071 | } /* end if */ |
1072 | |
1073 | } else if ( _move_dir_proc != NULL ) |
1074 | |
1075 | ( *_move_dir_proc ) ( pFullNameSrc, pFullNameDst ); |
1076 | |
1077 | } /* end else */ |
1078 | |
1079 | HeapFree ( hHeap, 0, pFullNameDst ); |
1080 | HeapFree ( hHeap, 0, pFullNameSrc ); |
1081 | pFullNameSrc = pFullNameDst = NULL; |
1082 | |
1083 | } /* end if */ |
1084 | |
d9ff84e8 |
1085 | fFind = FindNextFileW ( hFindFile, pFD ); |
7fd59977 |
1086 | |
1087 | } /* end while */ |
1088 | |
1089 | } /* end if */ |
1090 | |
1091 | } /* end if ( error creating directory ) */ |
1092 | |
1093 | if ( hFindFile != INVALID_HANDLE_VALUE ) FindClose ( hFindFile ); |
1094 | |
1095 | if ( pFullNameSrc != NULL ) HeapFree ( hHeap, 0, pFullNameSrc ); |
1096 | if ( pFullNameDst != NULL ) HeapFree ( hHeap, 0, pFullNameDst ); |
1097 | if ( pName != NULL ) HeapFree ( hHeap, 0, pName ); |
1098 | if ( pFD != NULL ) HeapFree ( hHeap, 0, pFD ); |
1099 | |
1100 | if ( retVal ) { |
1101 | retry_2: |
d9ff84e8 |
1102 | retVal = RemoveDirectoryW ( oldDir ); |
7fd59977 |
1103 | |
1104 | if ( !retVal ) { |
1105 | |
1106 | if ( _response_dir_proc != NULL ) { |
1107 | |
1108 | response = ( *_response_dir_proc ) ( oldDir ); |
1109 | |
1110 | if ( response == DIR_RETRY ) |
1111 | |
1112 | goto retry_2; |
1113 | |
1114 | else if ( response == DIR_IGNORE ) |
1115 | |
1116 | retVal = TRUE; |
1117 | |
1118 | } /* end if */ |
1119 | |
1120 | } /* end if */ |
1121 | |
1122 | } /* end if */ |
1123 | |
1124 | --level; |
1125 | TlsSetValue ( dwLevel, ( LPVOID )level ); |
1126 | |
1127 | return retVal; |
1128 | |
1129 | } /* end MoveDirectory */ |
1130 | /***/ |
1131 | /******************************************************************************/ |
1132 | /* Function : CopyDirectory */ |
1133 | /* Purpose : Copies specified directory tree to the new location */ |
1134 | /* Returns : TRUE on success, FALSE otherwise */ |
1135 | /******************************************************************************/ |
1136 | /***/ |
d9ff84e8 |
1137 | BOOL CopyDirectory ( LPCWSTR dirSrc, LPCWSTR dirDst ) { |
7fd59977 |
1138 | |
d9ff84e8 |
1139 | PWIN32_FIND_DATAW pFD = NULL; |
1140 | LPWSTR pName = NULL; |
1141 | LPWSTR pFullNameSrc = NULL; |
1142 | LPWSTR pFullNameDst = NULL; |
1143 | HANDLE hFindFile = INVALID_HANDLE_VALUE; |
1144 | BOOL fFind; |
1145 | BOOL retVal = FALSE; |
1146 | DIR_RESPONSE response; |
7fd59977 |
1147 | |
d9ff84e8 |
1148 | retVal = CreateDirectoryW ( dirDst, NULL ); |
7fd59977 |
1149 | |
1150 | if ( retVal || ( !retVal && GetLastError () == ERROR_ALREADY_EXISTS ) ) { |
1151 | |
d9ff84e8 |
1152 | if ( ( pFD = ( PWIN32_FIND_DATAW )HeapAlloc ( |
1153 | hHeap, 0, sizeof ( WIN32_FIND_DATAW ) |
7fd59977 |
1154 | ) |
1155 | ) != NULL && |
d9ff84e8 |
1156 | ( pName = ( LPWSTR )HeapAlloc ( |
1157 | hHeap, 0, lstrlenW ( dirSrc ) + WILD_CARD_LEN + |
1158 | sizeof ( L'\x00' ) |
7fd59977 |
1159 | ) |
1160 | ) != NULL |
1161 | ) { |
1162 | |
d9ff84e8 |
1163 | lstrcpyW ( pName, dirSrc ); |
1164 | lstrcatW ( pName, WILD_CARD ); |
7fd59977 |
1165 | |
1166 | retVal = TRUE; |
d9ff84e8 |
1167 | fFind = ( hFindFile = FindFirstFileW ( pName, pFD ) ) != INVALID_HANDLE_VALUE; |
7fd59977 |
1168 | |
1169 | while ( fFind ) { |
1170 | |
d9ff84e8 |
1171 | if ( pFD -> cFileName[ 0 ] != L'.' || |
1172 | pFD -> cFileName[ 0 ] != L'.' && |
1173 | pFD -> cFileName[ 1 ] != L'.' |
7fd59977 |
1174 | ) { |
1175 | |
d9ff84e8 |
1176 | if ( ( pFullNameSrc = ( LPWSTR )HeapAlloc ( |
7fd59977 |
1177 | hHeap, 0, |
d9ff84e8 |
1178 | lstrlenW ( dirSrc ) + lstrlenW ( pFD -> cFileName ) + |
1179 | sizeof ( L'/' ) + sizeof ( L'\x00' ) |
7fd59977 |
1180 | ) |
1181 | ) == NULL || |
d9ff84e8 |
1182 | ( pFullNameDst = ( LPWSTR )HeapAlloc ( |
7fd59977 |
1183 | hHeap, 0, |
d9ff84e8 |
1184 | lstrlenW ( dirDst ) + lstrlenW ( pFD -> cFileName ) + |
1185 | sizeof ( L'/' ) + sizeof ( L'\x00' ) |
7fd59977 |
1186 | ) |
1187 | ) == NULL |
1188 | ) break; |
1189 | |
d9ff84e8 |
1190 | lstrcpyW ( pFullNameSrc, dirSrc ); |
1191 | lstrcatW ( pFullNameSrc, L"/" ); |
1192 | lstrcatW ( pFullNameSrc, pFD -> cFileName ); |
7fd59977 |
1193 | |
d9ff84e8 |
1194 | lstrcpyW ( pFullNameDst, dirDst ); |
1195 | lstrcatW ( pFullNameDst, L"/" ); |
1196 | lstrcatW ( pFullNameDst, pFD -> cFileName ); |
7fd59977 |
1197 | |
1198 | if ( pFD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { |
1199 | |
302f96fb |
1200 | retVal = CopyDirectory ( pFullNameSrc, pFullNameDst ); |
1201 | if ( ! retVal ) break; |
7fd59977 |
1202 | |
1203 | } else { |
1204 | retry: |
d9ff84e8 |
1205 | retVal = CopyFileW ( pFullNameSrc, pFullNameDst, FALSE ); |
302f96fb |
1206 | if ( ! retVal ) { |
7fd59977 |
1207 | |
1208 | if ( _response_dir_proc != NULL ) { |
1209 | |
1210 | response = ( *_response_dir_proc ) ( pFullNameSrc ); |
1211 | |
1212 | if ( response == DIR_ABORT ) |
1213 | |
1214 | break; |
1215 | |
1216 | else if ( response == DIR_RETRY ) |
1217 | |
1218 | goto retry; |
1219 | |
1220 | else if ( response == DIR_IGNORE ) |
1221 | |
1222 | retVal = TRUE; |
1223 | |
1224 | else |
1225 | |
1226 | break; |
1227 | |
1228 | } /* end if */ |
1229 | |
1230 | } else if ( _copy_dir_proc != NULL ) |
1231 | |
1232 | ( *_copy_dir_proc ) ( pFullNameSrc, pFullNameDst ); |
1233 | |
1234 | } /* end else */ |
1235 | |
1236 | HeapFree ( hHeap, 0, pFullNameDst ); |
1237 | HeapFree ( hHeap, 0, pFullNameSrc ); |
1238 | pFullNameSrc = pFullNameDst = NULL; |
1239 | |
1240 | } /* end if */ |
1241 | |
d9ff84e8 |
1242 | fFind = FindNextFileW ( hFindFile, pFD ); |
7fd59977 |
1243 | |
1244 | } /* end while */ |
1245 | |
1246 | } /* end if */ |
1247 | |
1248 | } /* end if ( error creating directory ) */ |
1249 | |
1250 | if ( hFindFile != INVALID_HANDLE_VALUE ) FindClose ( hFindFile ); |
1251 | |
1252 | if ( pFullNameSrc != NULL ) HeapFree ( hHeap, 0, pFullNameSrc ); |
1253 | if ( pFullNameDst != NULL ) HeapFree ( hHeap, 0, pFullNameDst ); |
1254 | if ( pName != NULL ) HeapFree ( hHeap, 0, pName ); |
1255 | if ( pFD != NULL ) HeapFree ( hHeap, 0, pFD ); |
1256 | |
1257 | return retVal; |
1258 | |
1259 | } /* end CopyDirectory */ |
1260 | /***/ |
1261 | /******************************************************************************/ |
7fd59977 |
1262 | /* Function : SetMoveDirectoryProc */ |
1263 | /* Purpose : Sets callback procedure which is calling by the */ |
1264 | /* 'MoveDirectory' after moving of each item in the */ |
1265 | /* directory. To unregister this callback function supply NULL */ |
1266 | /* pointer */ |
1267 | /******************************************************************************/ |
1268 | /***/ |
1269 | void SetMoveDirectoryProc ( MOVE_DIR_PROC proc ) { |
1270 | |
1271 | _move_dir_proc = proc; |
1272 | |
1273 | } /* end SetMoveDirectoryProc */ |
1274 | /***/ |
1275 | /******************************************************************************/ |
1276 | /* Function : SetCopyDirectoryProc */ |
1277 | /* Purpose : Sets callback procedure which is calling by the */ |
1278 | /* 'CopyDirectory' after copying of each item in the */ |
1279 | /* directory. To unregister this callback function supply NULL */ |
1280 | /* pointer */ |
1281 | /******************************************************************************/ |
1282 | /***/ |
1283 | void SetCopyDirectoryProc ( COPY_DIR_PROC proc ) { |
1284 | |
1285 | _copy_dir_proc = proc; |
1286 | |
1287 | } /* end SetCopyDirectoryProc */ |
1288 | /***/ |
1289 | /******************************************************************************/ |
1290 | /* Function : SetResponseDirectoryProc */ |
1291 | /* Purpose : Sets callback procedure which is calling by the */ |
1292 | /* directoy processing function if an error was occur. */ |
1293 | /* The return value of that callback procedure determines */ |
1294 | /* behaviour of directoy processing functions in case of error. */ |
1295 | /* To unregister this callback function supply NULL pointer */ |
1296 | /******************************************************************************/ |
1297 | /***/ |
1298 | void SetResponseDirectoryProc ( RESPONSE_DIR_PROC proc ) { |
1299 | |
1300 | _response_dir_proc = proc; |
1301 | |
1302 | } /* end SetResponseDirectoryProc */ |
1303 | /***/ |
1304 | /******************************************************************************/ |
1305 | /******************************************************************************/ |
1306 | /******************************************************************************/ |
1307 | #endif |