1 // Created by: PLOTNIKOV Eugeny
2 // Copyright (c) 1996-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
18 /******************************************************************************/
19 /* File: OSD_WNT.cxx */
20 /* Purpose: Security management routines ( more convinient than WIN32 */
21 /* ones ) and other convinient functions. */
22 /******************************************************************************/
24 #include <OSD_WNT_1.hxx>
29 static void Init ( void );
31 class Init_OSD_WNT { // provides initialization
35 Init_OSD_WNT () { Init (); }
37 }; // end Init_OSD_WNT
39 static Init_OSD_WNT initOsdWnt;
41 static BOOL fInit = FALSE;
42 static PSID* predefinedSIDs;
45 static MOVE_DIR_PROC _move_dir_proc;
46 static COPY_DIR_PROC _copy_dir_proc;
47 static RESPONSE_DIR_PROC _response_dir_proc;
49 #define PREDEFINED_SIDs_COUNT 9
50 #define UNIVERSAL_PREDEFINED_SIDs_COUNT 5
52 #define SID_INTERACTIVE 0
57 #define SID_CREATOR_OWNER 5
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 /******************************************************************************/
69 PSECURITY_DESCRIPTOR AllocSD ( void ) {
71 PSECURITY_DESCRIPTOR retVal =
72 ( PSECURITY_DESCRIPTOR )HeapAlloc (
73 hHeap, 0, sizeof ( SECURITY_DESCRIPTOR )
76 if ( retVal != NULL &&
77 !InitializeSecurityDescriptor ( retVal, SECURITY_DESCRIPTOR_REVISION )
80 HeapFree ( hHeap, 0, ( PVOID )retVal );
89 /******************************************************************************/
90 /* Function : FreeSD */
91 /* Purpose : Deallocates security identifier which was allocated by the */
92 /* 'AllocSD' function */
93 /******************************************************************************/
95 void FreeSD ( PSECURITY_DESCRIPTOR pSD ) {
101 if ( GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDaclDefaulted ) &&
105 HeapFree ( hHeap, 0, ( PVOID )pACL );
107 HeapFree ( hHeap, 0, ( PVOID )pSD );
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 /******************************************************************************/
120 #if defined(__CYGWIN32__) || defined(__MINGW32__)
123 #define __leave return buffer
126 LPVOID GetTokenInformationEx ( HANDLE hToken, TOKEN_INFORMATION_CLASS tic ) {
130 DWORD dwSizeNeeded = 0;
131 LPVOID buffer = NULL;
138 dwSize = dwSizeNeeded;
139 errVal = ERROR_SUCCESS;
141 if ( !GetTokenInformation ( hToken, tic, buffer, dwSize, &dwSizeNeeded ) ) {
143 if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER )
147 if ( ( buffer = HeapAlloc ( hHeap, 0, dwSizeNeeded ) ) == NULL )
153 } while ( errVal != ERROR_SUCCESS );
161 if ( !fOK && buffer != NULL ) {
163 HeapFree ( hHeap, 0, buffer );
168 } /* end __finally */
171 leave: ; // added for VisualAge
176 } /* end GetTokenInformationEx */
178 #if defined(__CYGWIN32__) || defined(__MINGW32__)
185 /******************************************************************************/
186 /* Function : FreeTokenInformation */
187 /* Purpose : Deallocates access token which was allocated by the */
188 /* 'GetTokenInformationEx' function */
189 /******************************************************************************/
191 void FreeTokenInformation ( LPVOID lpvTkInfo ) {
193 HeapFree ( hHeap, 0, lpvTkInfo );
195 } /* end FreeTokenInformation */
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 /******************************************************************************/
206 static void Init ( void ) {
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;
216 predefinedSIDs = ( PSID* )HeapAlloc (
217 hHeap = GetProcessHeap (),
218 HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
219 PREDEFINED_SIDs_COUNT * sizeof ( PSID* )
222 AllocateAndInitializeSid (
223 &sidIDANT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
224 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_ADMIN ]
227 AllocateAndInitializeSid (
228 &sidIDAworld, 1, SECURITY_WORLD_RID,
229 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_WORLD ]
232 AllocateAndInitializeSid (
233 &sidIDANT, 1, SECURITY_INTERACTIVE_RID,
234 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_INTERACTIVE ]
237 AllocateAndInitializeSid (
238 &sidIDANT, 1, SECURITY_NETWORK_RID,
239 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NETWORK ]
242 AllocateAndInitializeSid (
243 &sidIDAlocal, 1, SECURITY_LOCAL_RID,
244 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_LOCAL ]
247 AllocateAndInitializeSid (
248 &sidIDANT, 1, SECURITY_DIALUP_RID,
249 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_DIALUP ]
252 AllocateAndInitializeSid (
253 &sidIDANT, 1, SECURITY_BATCH_RID,
254 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_BATCH ]
257 AllocateAndInitializeSid (
258 &sidIDAcreator, 1, SECURITY_CREATOR_OWNER_RID,
259 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_CREATOR_OWNER ]
262 AllocateAndInitializeSid (
263 &sidIDAnull, 1, SECURITY_NULL_RID,
264 0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NULL ]
273 /******************************************************************************/
274 /* Function : PredefinedSid */
275 /* Purpose : Checks whether specified SID predefined or not */
276 /* Returns : TRUE if specified SID is predefined, FALSE otherwise */
277 /******************************************************************************/
279 BOOL PredefinedSid ( PSID pSID ) {
283 for ( i = 0; i < PREDEFINED_SIDs_COUNT; ++i )
285 if ( EqualSid ( pSID, predefinedSIDs[ i ] ) )
291 } /* end PredefinedSid */
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 /******************************************************************************/
299 BOOL NtPredefinedSid ( PSID pSID ) {
302 PSID_IDENTIFIER_AUTHORITY pTestIDA;
303 SID_IDENTIFIER_AUTHORITY ntIDA = SECURITY_NT_AUTHORITY;
306 for ( i = 0; i < UNIVERSAL_PREDEFINED_SIDs_COUNT; ++i )
308 if ( EqualSid ( pSID, predefinedSIDs[ i ] ) )
312 pTestIDA = GetSidIdentifierAuthority ( pSID );
314 if ( memcmp ( pTestIDA, &ntIDA, sizeof ( SID_IDENTIFIER_AUTHORITY ) ) == 0 ) {
316 pdwTestSA = GetSidSubAuthority ( pSID, 0 );
318 if ( *pdwTestSA == SECURITY_LOGON_IDS_RID )
326 } /* end NtPredefinedSid */
328 /******************************************************************************/
329 /* Function : AdminSid */
330 /* Purpose : Returns SID of the administrative user account */
331 /******************************************************************************/
333 PSID AdminSid ( void ) {
335 return predefinedSIDs[ SID_ADMIN ];
339 /******************************************************************************/
340 /* Function : WorldSid */
341 /* Purpose : Returns SID of group that includes all users */
342 /******************************************************************************/
344 PSID WorldSid ( void ) {
346 return predefinedSIDs[ SID_WORLD ];
350 /******************************************************************************/
351 /* Function : InteractiveSid */
352 /* Purpose : Returns SID of group that includes all users logged on for */
353 /* interactive operation */
354 /******************************************************************************/
356 PSID InteractiveSid ( void ) {
358 return predefinedSIDs[ SID_INTERACTIVE ];
360 } /* end InteractiveSID */
362 /******************************************************************************/
363 /* Function : NetworkSid */
364 /* Purpose : Returns SID of group that includes all users logged on across */
366 /******************************************************************************/
368 PSID NetworkSid ( void ) {
370 return predefinedSIDs[ SID_NETWORK ];
372 } /* end NetworkSid */
374 /******************************************************************************/
375 /* Function : LocalSid */
376 /* Purpose : Returns SID of group that includes all users logged on locally*/
377 /******************************************************************************/
379 PSID LocalSid ( void ) {
381 return predefinedSIDs[ SID_LOCAL ];
385 /******************************************************************************/
386 /* Function : DialupSid */
387 /* Purpose : Returns SID of group that includes all users logged on to */
388 /* terminals using a dialup modem */
389 /******************************************************************************/
391 PSID DialupSid ( void ) {
393 return predefinedSIDs[ SID_DIALUP ];
395 } /* end DialupSid */
397 /******************************************************************************/
398 /* Function : BatchSid */
399 /* Purpose : Returns SID of group that includes all users logged on using */
400 /* a batch queue facility */
401 /******************************************************************************/
403 PSID BatchSid ( void ) {
405 return predefinedSIDs[ SID_BATCH ];
409 /******************************************************************************/
410 /* Function : CreatorOwnerSid */
411 /* Purpose : Returns SID of 'CREATOR OWNER' special group */
412 /******************************************************************************/
414 PSID CreatorOwnerSid ( void ) {
416 return predefinedSIDs[ SID_CREATOR_OWNER ];
418 } /* end CreatorOwnerSid */
420 /******************************************************************************/
421 /* Function : NullSid */
422 /* Purpose : Returns null SID */
423 /******************************************************************************/
425 PSID NullSid ( void ) {
427 return predefinedSIDs[ SID_NULL ];
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 */
437 /* Warning : Allocated security descriptor must be deallocated by */
438 /* 'FreeFileSecurity' function */
439 /******************************************************************************/
443 #if defined(__CYGWIN32__) || defined(__MINGW32__)
446 #define __leave return retVal
449 PSECURITY_DESCRIPTOR GetFileSecurityEx ( LPCWSTR fileName, SECURITY_INFORMATION si ) {
453 DWORD dwSizeNeeded = 0;
454 PSECURITY_DESCRIPTOR retVal = NULL;
461 dwSize = dwSizeNeeded;
462 errVal = ERROR_SUCCESS;
464 if ( !GetFileSecurityW (
466 retVal, dwSize, &dwSizeNeeded
470 if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER ) __leave;
472 if ( ( retVal = ( PSECURITY_DESCRIPTOR )HeapAlloc ( hHeap, 0, dwSizeNeeded )
478 } while ( errVal != ERROR_SUCCESS );
486 if ( !fOK && retVal != NULL ) {
488 HeapFree ( hHeap, 0, retVal );
493 } /* end __finally */
496 leave: ; // added for VisualAge
501 } /* end GetFileSecurityEx */
503 #if defined(__CYGWIN32__) || defined(__MINGW32__)
510 /******************************************************************************/
511 /* Function : FreeFileSecurity */
512 /* Purpose : Deallocates security descriptor which was allocated by the */
513 /* 'GetFileSecurityEx' function */
514 /******************************************************************************/
516 void FreeFileSecurity ( PSECURITY_DESCRIPTOR pSD ) {
518 HeapFree ( hHeap, 0, ( LPVOID )pSD );
520 } /* end FreeFileSecurity */
523 /******************************************************************************/
524 /* Function : CreateAcl */
525 /* Purpose : Allocates and initializes access-control list */
526 /* Returns : Pointer to the allocated and initialized ACL on success, */
528 /* Warning : Allocated ACL must be deallocated by 'FreeAcl' function */
529 /******************************************************************************/
531 PACL CreateAcl ( DWORD dwAclSize ) {
535 retVal = ( PACL )HeapAlloc ( hHeap, 0, dwAclSize );
537 if ( retVal != NULL )
539 InitializeAcl ( retVal, dwAclSize, ACL_REVISION );
543 } /* end CreateAcl */
545 /******************************************************************************/
546 /* Function : FreeAcl */
547 /* Purpose : Deallocates access-control list which was allocated by the */
548 /* 'CreateAcl' function */
549 /******************************************************************************/
551 void FreeAcl ( PACL pACL ) {
553 HeapFree ( hHeap, 0, ( PVOID )pACL );
557 /******************************************************************************/
558 /* Function : AllocAccessAllowedAce */
559 /* Purpose : Allocates and initializes access-control entry */
560 /* Returns : Pointer to the ACE on success, NULL othrwise */
561 /* Warning : Allocated ACE must be deallocated by the 'FreeAce' function */
562 /******************************************************************************/
564 PVOID AllocAccessAllowedAce ( DWORD dwMask, BYTE flags, PSID pSID ) {
569 wSize = (WORD)( sizeof ( ACE_HEADER ) + sizeof ( DWORD ) + GetLengthSid ( pSID ) );
571 retVal = ( PFILE_ACE )HeapAlloc ( hHeap, 0, wSize );
573 if ( retVal != NULL ) {
575 retVal -> header.AceType = ACCESS_ALLOWED_ACE_TYPE;
576 retVal -> header.AceFlags = flags;
577 retVal -> header.AceSize = wSize;
579 retVal -> dwMask = dwMask;
581 CopySid ( GetLengthSid ( pSID ), &retVal -> pSID, pSID );
587 } /* end AllocAccessAllowedAce */
589 /******************************************************************************/
590 /* Function : FreeAce */
591 /* Purpose : Deallocates an ACE which was allocated by the */
592 /* 'AllocAccessAllowedAce ' function */
593 /******************************************************************************/
595 void FreeAce ( PVOID pACE ) {
597 HeapFree ( hHeap, 0, pACE );
601 #define WILD_CARD L"/*.*"
602 #define WILD_CARD_LEN ( sizeof ( WILD_CARD ) )
605 /******************************************************************************/
606 /* Function : MoveDirectory */
607 /* Purpose : Moves specified directory tree to the new location */
608 /* Returns : TRUE on success, FALSE otherwise */
609 /******************************************************************************/
611 static BOOL MoveDirectory ( LPCWSTR oldDir, LPCWSTR newDir, DWORD& theRecurseLevel ) {
613 PWIN32_FIND_DATAW pFD;
617 LPWSTR driveSrc, driveDst;
618 LPWSTR pathSrc, pathDst;
622 DIR_RESPONSE response;
624 if (theRecurseLevel == 0) {
629 driveSrc = driveDst = pathSrc = pathDst = NULL;
631 if ( ( driveSrc = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DRIVE * sizeof(WCHAR) ) ) != NULL &&
632 ( driveDst = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DRIVE * sizeof(WCHAR) ) ) != NULL &&
633 ( pathSrc = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DIR * sizeof(WCHAR) ) ) != NULL &&
634 ( pathDst = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DIR * sizeof(WCHAR) ) ) != NULL
637 _wsplitpath ( oldDir, driveSrc, pathSrc, NULL, NULL );
638 _wsplitpath ( newDir, driveDst, pathDst, NULL, NULL );
640 if ( wcscmp ( driveSrc, driveDst ) == 0 &&
641 wcscmp ( pathSrc, pathDst ) == 0
644 retVal = MoveFileExW (
645 oldDir, newDir, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
651 if ( _response_dir_proc != NULL ) {
653 response = ( *_response_dir_proc ) ( oldDir );
655 if ( response == DIR_RETRY )
659 else if ( response == DIR_IGNORE )
665 } else if ( _move_dir_proc != NULL )
667 ( *_move_dir_proc ) ( oldDir, newDir );
673 if ( pathDst != NULL ) HeapFree ( hHeap, 0, pathDst );
674 if ( pathSrc != NULL ) HeapFree ( hHeap, 0, pathSrc );
675 if ( driveDst != NULL ) HeapFree ( hHeap, 0, driveDst );
676 if ( driveSrc != NULL ) HeapFree ( hHeap, 0, driveSrc );
693 pFullNameSrc = pFullNameDst = NULL;
694 hFindFile = INVALID_HANDLE_VALUE;
697 retVal = CreateDirectoryW ( newDir, NULL );
699 if ( retVal || ( !retVal && GetLastError () == ERROR_ALREADY_EXISTS ) ) {
701 if ( ( pFD = ( PWIN32_FIND_DATAW )HeapAlloc (
702 hHeap, 0, sizeof ( WIN32_FIND_DATAW )
705 ( pName = ( LPWSTR )HeapAlloc (
706 hHeap, 0, lstrlenW ( oldDir ) + WILD_CARD_LEN +
712 lstrcpyW ( pName, oldDir );
713 lstrcatW ( pName, WILD_CARD );
716 fFind = ( hFindFile = FindFirstFileW ( pName, pFD ) ) != INVALID_HANDLE_VALUE;
720 if ( pFD -> cFileName[ 0 ] != L'.' ||
721 pFD -> cFileName[ 0 ] != L'.' &&
722 pFD -> cFileName[ 1 ] != L'.'
725 if ( ( pFullNameSrc = ( LPWSTR )HeapAlloc (
727 lstrlenW ( oldDir ) + lstrlenW ( pFD -> cFileName ) +
728 sizeof ( L'/' ) + sizeof ( L'\x00' )
731 ( pFullNameDst = ( LPWSTR )HeapAlloc (
733 lstrlenW ( newDir ) + lstrlenW ( pFD -> cFileName ) +
734 sizeof ( L'/' ) + sizeof ( L'\x00' )
739 lstrcpyW ( pFullNameSrc, oldDir );
740 lstrcatW ( pFullNameSrc, L"/" );
741 lstrcatW ( pFullNameSrc, pFD -> cFileName );
743 lstrcpyW ( pFullNameDst, newDir );
744 lstrcatW ( pFullNameDst, L"/" );
745 lstrcatW ( pFullNameDst, pFD -> cFileName );
747 if ( pFD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
749 retVal = MoveDirectory ( pFullNameSrc, pFullNameDst, theRecurseLevel );
754 retVal = MoveFileExW (pFullNameSrc, pFullNameDst,
755 MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
758 if ( _response_dir_proc != NULL ) {
760 response = ( *_response_dir_proc ) ( pFullNameSrc );
762 if ( response == DIR_ABORT )
766 else if ( response == DIR_RETRY )
770 else if ( response == DIR_IGNORE )
780 } else if ( _move_dir_proc != NULL )
782 ( *_move_dir_proc ) ( pFullNameSrc, pFullNameDst );
786 HeapFree ( hHeap, 0, pFullNameDst );
787 HeapFree ( hHeap, 0, pFullNameSrc );
788 pFullNameSrc = pFullNameDst = NULL;
792 fFind = FindNextFileW ( hFindFile, pFD );
798 } /* end if ( error creating directory ) */
800 if ( hFindFile != INVALID_HANDLE_VALUE ) FindClose ( hFindFile );
802 if ( pFullNameSrc != NULL ) HeapFree ( hHeap, 0, pFullNameSrc );
803 if ( pFullNameDst != NULL ) HeapFree ( hHeap, 0, pFullNameDst );
804 if ( pName != NULL ) HeapFree ( hHeap, 0, pName );
805 if ( pFD != NULL ) HeapFree ( hHeap, 0, pFD );
809 retVal = RemoveDirectoryW ( oldDir );
813 if ( _response_dir_proc != NULL ) {
815 response = ( *_response_dir_proc ) ( oldDir );
817 if ( response == DIR_RETRY )
821 else if ( response == DIR_IGNORE )
835 } /* end MoveDirectory */
837 BOOL MoveDirectory (LPCWSTR oldDir, LPCWSTR newDir)
839 DWORD aRecurseLevel = 0;
840 return MoveDirectory (oldDir, newDir, aRecurseLevel);
844 /******************************************************************************/
845 /* Function : CopyDirectory */
846 /* Purpose : Copies specified directory tree to the new location */
847 /* Returns : TRUE on success, FALSE otherwise */
848 /******************************************************************************/
850 BOOL CopyDirectory ( LPCWSTR dirSrc, LPCWSTR dirDst ) {
852 PWIN32_FIND_DATAW pFD = NULL;
854 LPWSTR pFullNameSrc = NULL;
855 LPWSTR pFullNameDst = NULL;
856 HANDLE hFindFile = INVALID_HANDLE_VALUE;
859 DIR_RESPONSE response;
861 retVal = CreateDirectoryW ( dirDst, NULL );
863 if ( retVal || ( !retVal && GetLastError () == ERROR_ALREADY_EXISTS ) ) {
865 if ( ( pFD = ( PWIN32_FIND_DATAW )HeapAlloc (
866 hHeap, 0, sizeof ( WIN32_FIND_DATAW )
869 ( pName = ( LPWSTR )HeapAlloc (
870 hHeap, 0, lstrlenW ( dirSrc ) + WILD_CARD_LEN +
876 lstrcpyW ( pName, dirSrc );
877 lstrcatW ( pName, WILD_CARD );
880 fFind = ( hFindFile = FindFirstFileW ( pName, pFD ) ) != INVALID_HANDLE_VALUE;
884 if ( pFD -> cFileName[ 0 ] != L'.' ||
885 pFD -> cFileName[ 0 ] != L'.' &&
886 pFD -> cFileName[ 1 ] != L'.'
889 if ( ( pFullNameSrc = ( LPWSTR )HeapAlloc (
891 lstrlenW ( dirSrc ) + lstrlenW ( pFD -> cFileName ) +
892 sizeof ( L'/' ) + sizeof ( L'\x00' )
895 ( pFullNameDst = ( LPWSTR )HeapAlloc (
897 lstrlenW ( dirDst ) + lstrlenW ( pFD -> cFileName ) +
898 sizeof ( L'/' ) + sizeof ( L'\x00' )
903 lstrcpyW ( pFullNameSrc, dirSrc );
904 lstrcatW ( pFullNameSrc, L"/" );
905 lstrcatW ( pFullNameSrc, pFD -> cFileName );
907 lstrcpyW ( pFullNameDst, dirDst );
908 lstrcatW ( pFullNameDst, L"/" );
909 lstrcatW ( pFullNameDst, pFD -> cFileName );
911 if ( pFD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
913 retVal = CopyDirectory ( pFullNameSrc, pFullNameDst );
914 if ( ! retVal ) break;
918 retVal = CopyFileW ( pFullNameSrc, pFullNameDst, FALSE );
921 if ( _response_dir_proc != NULL ) {
923 response = ( *_response_dir_proc ) ( pFullNameSrc );
925 if ( response == DIR_ABORT )
929 else if ( response == DIR_RETRY )
933 else if ( response == DIR_IGNORE )
943 } else if ( _copy_dir_proc != NULL )
945 ( *_copy_dir_proc ) ( pFullNameSrc, pFullNameDst );
949 HeapFree ( hHeap, 0, pFullNameDst );
950 HeapFree ( hHeap, 0, pFullNameSrc );
951 pFullNameSrc = pFullNameDst = NULL;
955 fFind = FindNextFileW ( hFindFile, pFD );
961 } /* end if ( error creating directory ) */
963 if ( hFindFile != INVALID_HANDLE_VALUE ) FindClose ( hFindFile );
965 if ( pFullNameSrc != NULL ) HeapFree ( hHeap, 0, pFullNameSrc );
966 if ( pFullNameDst != NULL ) HeapFree ( hHeap, 0, pFullNameDst );
967 if ( pName != NULL ) HeapFree ( hHeap, 0, pName );
968 if ( pFD != NULL ) HeapFree ( hHeap, 0, pFD );
972 } /* end CopyDirectory */
974 /******************************************************************************/
975 /* Function : SetMoveDirectoryProc */
976 /* Purpose : Sets callback procedure which is calling by the */
977 /* 'MoveDirectory' after moving of each item in the */
978 /* directory. To unregister this callback function supply NULL */
980 /******************************************************************************/
982 void SetMoveDirectoryProc ( MOVE_DIR_PROC proc ) {
984 _move_dir_proc = proc;
986 } /* end SetMoveDirectoryProc */
988 /******************************************************************************/
989 /* Function : SetCopyDirectoryProc */
990 /* Purpose : Sets callback procedure which is calling by the */
991 /* 'CopyDirectory' after copying of each item in the */
992 /* directory. To unregister this callback function supply NULL */
994 /******************************************************************************/
996 void SetCopyDirectoryProc ( COPY_DIR_PROC proc ) {
998 _copy_dir_proc = proc;
1000 } /* end SetCopyDirectoryProc */
1002 /******************************************************************************/
1003 /* Function : SetResponseDirectoryProc */
1004 /* Purpose : Sets callback procedure which is calling by the */
1005 /* directoy processing function if an error was occur. */
1006 /* The return value of that callback procedure determines */
1007 /* behaviour of directoy processing functions in case of error. */
1008 /* To unregister this callback function supply NULL pointer */
1009 /******************************************************************************/
1011 void SetResponseDirectoryProc ( RESPONSE_DIR_PROC proc ) {
1013 _response_dir_proc = proc;
1015 } /* end SetResponseDirectoryProc */
1017 /******************************************************************************/
1018 /******************************************************************************/
1019 /******************************************************************************/