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