1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-16 10:54:53 +03:00
occt/src/OSD/OSD_WNT.cxx
ski 742cc8b01d 0027350: Support for Universal Windows Platform
- Toolchain file to configure a Visual Studio generator for a Windows 10 Universal Application was added (CMake).
- There is no support for environment variables in UWP.
- SID is not supported (were excluded).
- Windows registry is not supported (were excluded).
- Mess with usage of Unicode/ANSI was corrected.
- Added sample to check UWP functionality.
- Excluded usage of methods with Unicode characters where it is possible.
- Minor corrections to allow building OCAF (except TKVCAF) and DE (except VRML and XDE)
- Building of unsupported modules for UWP platform is off by default .
- Checking of DataExchange functionality was added to XAML (UWP) sample.
- Added information about UWP to the documentation.
- Update of results of merge with issue 27801
2016-08-26 09:43:29 +03:00

1051 lines
34 KiB
C++

// Created by: PLOTNIKOV Eugeny
// Copyright (c) 1996-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifdef _WIN32
/******************************************************************************/
/* File: OSD_WNT.cxx */
/* Purpose: Security management routines ( more convinient than WIN32 */
/* ones ) and other convinient functions. */
/******************************************************************************/
/***/
#include <OSD_WNT_1.hxx>
#include <Strsafe.h>
#include <wchar.h>
#include <stdlib.h>
#include <Standard_Macro.hxx>
/***/
#ifndef OCCT_UWP
static void Init ( void );
/***/
class Init_OSD_WNT { // provides initialization
public:
Init_OSD_WNT () { Init (); }
}; // end Init_OSD_WNT
static Init_OSD_WNT initOsdWnt;
#endif
/***/
static BOOL fInit = FALSE;
static PSID* predefinedSIDs;
static HANDLE hHeap;
/***/
static MOVE_DIR_PROC _move_dir_proc;
static COPY_DIR_PROC _copy_dir_proc;
static RESPONSE_DIR_PROC _response_dir_proc;
/***/
#define PREDEFINED_SIDs_COUNT 9
#define UNIVERSAL_PREDEFINED_SIDs_COUNT 5
/***/
#define SID_INTERACTIVE 0
#define SID_NETWORK 1
#define SID_LOCAL 2
#define SID_DIALUP 3
#define SID_BATCH 4
#define SID_CREATOR_OWNER 5
#define SID_ADMIN 6
#define SID_WORLD 7
#define SID_NULL 8
/***/
#ifndef OCCT_UWP
// None of the existing security APIs are supported in a UWP applications
/******************************************************************************/
/* Function : AllocSD */
/* Purpose : Allocates and initializes security identifier */
/* Returns : Pointer to allocated SID on success, NULL otherwise */
/* Warning : Allocated SID must be deallocated by 'FreeSD' function */
/******************************************************************************/
/***/
PSECURITY_DESCRIPTOR AllocSD ( void ) {
PSECURITY_DESCRIPTOR retVal =
( PSECURITY_DESCRIPTOR )HeapAlloc (
hHeap, 0, sizeof ( SECURITY_DESCRIPTOR )
);
if ( retVal != NULL &&
!InitializeSecurityDescriptor ( retVal, SECURITY_DESCRIPTOR_REVISION )
) {
HeapFree ( hHeap, 0, ( PVOID )retVal );
retVal = NULL;
} /* end if */
return retVal;
} /* end AllocSD */
/***/
/******************************************************************************/
/* Function : FreeSD */
/* Purpose : Deallocates security identifier which was allocated by the */
/* 'AllocSD' function */
/******************************************************************************/
/***/
void FreeSD ( PSECURITY_DESCRIPTOR pSD ) {
BOOL fPresent;
BOOL fDaclDefaulted;
PACL pACL;
if ( GetSecurityDescriptorDacl ( pSD, &fPresent, &pACL, &fDaclDefaulted ) &&
fPresent
)
HeapFree ( hHeap, 0, ( PVOID )pACL );
HeapFree ( hHeap, 0, ( PVOID )pSD );
} /* end FreeSD */
/***/
/******************************************************************************/
/* Function : GetTokenInformationEx */
/* Purpose : Allocates and fills out access token */
/* Returns : Pointer to the access token on success, NULL otherwise */
/* Warning : Allocated access token must be deallocated by */
/* 'FreeTokenInformation' function */
/******************************************************************************/
/***/
#if defined(__CYGWIN32__) || defined(__MINGW32__)
#define __try
#define __finally
#define __leave return buffer
#endif
LPVOID GetTokenInformationEx ( HANDLE hToken, TOKEN_INFORMATION_CLASS tic ) {
DWORD errVal;
DWORD dwSize;
DWORD dwSizeNeeded = 0;
LPVOID buffer = NULL;
BOOL fOK = FALSE;
__try {
do {
dwSize = dwSizeNeeded;
errVal = ERROR_SUCCESS;
if ( !GetTokenInformation ( hToken, tic, buffer, dwSize, &dwSizeNeeded ) ) {
if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER )
__leave;
if ( ( buffer = HeapAlloc ( hHeap, 0, dwSizeNeeded ) ) == NULL )
__leave;
} /* end if */
} while ( errVal != ERROR_SUCCESS );
fOK = TRUE;
} /* end __try */
__finally {
if ( !fOK && buffer != NULL ) {
HeapFree ( hHeap, 0, buffer );
buffer = NULL;
} /* end if */
} /* end __finally */
#ifdef VAC
leave: ; // added for VisualAge
#endif
return buffer;
} /* end GetTokenInformationEx */
#if defined(__CYGWIN32__) || defined(__MINGW32__)
#undef __try
#undef __finally
#undef __leave
#endif
/***/
/******************************************************************************/
/* Function : FreeTokenInformation */
/* Purpose : Deallocates access token which was allocated by the */
/* 'GetTokenInformationEx' function */
/******************************************************************************/
/***/
void FreeTokenInformation ( LPVOID lpvTkInfo ) {
HeapFree ( hHeap, 0, lpvTkInfo );
} /* end FreeTokenInformation */
/***/
/******************************************************************************/
/* Function : Init */
/* Purpose : Allocates and initializes predefined security identifiers */
/* Warning : Generates 'STATUS_NO_MEMORY' software exception if there are */
/* insufficient of memory. This exception can be caught by using */
/* software exception handling ( SEH ) mechanism */
/* ( __try / __except ) */
/******************************************************************************/
/***/
static void Init ( void ) {
SID_IDENTIFIER_AUTHORITY sidIDAnull = SECURITY_NULL_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY sidIDAworld = SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY sidIDANT = SECURITY_NT_AUTHORITY;
SID_IDENTIFIER_AUTHORITY sidIDAlocal = SECURITY_LOCAL_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY sidIDAcreator = SECURITY_CREATOR_SID_AUTHORITY;
if ( !fInit ) {
predefinedSIDs = ( PSID* )HeapAlloc (
hHeap = GetProcessHeap (),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
PREDEFINED_SIDs_COUNT * sizeof ( PSID* )
);
AllocateAndInitializeSid (
&sidIDANT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_ADMIN ]
);
AllocateAndInitializeSid (
&sidIDAworld, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_WORLD ]
);
AllocateAndInitializeSid (
&sidIDANT, 1, SECURITY_INTERACTIVE_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_INTERACTIVE ]
);
AllocateAndInitializeSid (
&sidIDANT, 1, SECURITY_NETWORK_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NETWORK ]
);
AllocateAndInitializeSid (
&sidIDAlocal, 1, SECURITY_LOCAL_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_LOCAL ]
);
AllocateAndInitializeSid (
&sidIDANT, 1, SECURITY_DIALUP_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_DIALUP ]
);
AllocateAndInitializeSid (
&sidIDANT, 1, SECURITY_BATCH_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_BATCH ]
);
AllocateAndInitializeSid (
&sidIDAcreator, 1, SECURITY_CREATOR_OWNER_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_CREATOR_OWNER ]
);
AllocateAndInitializeSid (
&sidIDAnull, 1, SECURITY_NULL_RID,
0, 0, 0, 0, 0, 0, 0, &predefinedSIDs[ SID_NULL ]
);
fInit = TRUE;
} /* end if */
} /* end init */
/***/
/******************************************************************************/
/* Function : PredefinedSid */
/* Purpose : Checks whether specified SID predefined or not */
/* Returns : TRUE if specified SID is predefined, FALSE otherwise */
/******************************************************************************/
/***/
BOOL PredefinedSid ( PSID pSID ) {
int i;
for ( i = 0; i < PREDEFINED_SIDs_COUNT; ++i )
if ( EqualSid ( pSID, predefinedSIDs[ i ] ) )
return TRUE;
return FALSE;
} /* end PredefinedSid */
/***/
/******************************************************************************/
/* Function : NtPredefinedSid */
/* Purpose : Checks whether specified SID universal or not */
/* Returns : TRUE if specified SID is NOT universal, FALSE otherwise */
/******************************************************************************/
/***/
BOOL NtPredefinedSid ( PSID pSID ) {
int i;
PSID_IDENTIFIER_AUTHORITY pTestIDA;
SID_IDENTIFIER_AUTHORITY ntIDA = SECURITY_NT_AUTHORITY;
PDWORD pdwTestSA;
for ( i = 0; i < UNIVERSAL_PREDEFINED_SIDs_COUNT; ++i )
if ( EqualSid ( pSID, predefinedSIDs[ i ] ) )
return TRUE;
pTestIDA = GetSidIdentifierAuthority ( pSID );
if ( memcmp ( pTestIDA, &ntIDA, sizeof ( SID_IDENTIFIER_AUTHORITY ) ) == 0 ) {
pdwTestSA = GetSidSubAuthority ( pSID, 0 );
if ( *pdwTestSA == SECURITY_LOGON_IDS_RID )
return TRUE;
} /* end if */
return FALSE;
} /* end NtPredefinedSid */
/***/
/******************************************************************************/
/* Function : AdminSid */
/* Purpose : Returns SID of the administrative user account */
/******************************************************************************/
/***/
PSID AdminSid ( void ) {
return predefinedSIDs[ SID_ADMIN ];
} /* end AdminSid */
/***/
/******************************************************************************/
/* Function : WorldSid */
/* Purpose : Returns SID of group that includes all users */
/******************************************************************************/
/***/
PSID WorldSid ( void ) {
return predefinedSIDs[ SID_WORLD ];
} /* end WorldSid */
/***/
/******************************************************************************/
/* Function : InteractiveSid */
/* Purpose : Returns SID of group that includes all users logged on for */
/* interactive operation */
/******************************************************************************/
/***/
PSID InteractiveSid ( void ) {
return predefinedSIDs[ SID_INTERACTIVE ];
} /* end InteractiveSID */
/***/
/******************************************************************************/
/* Function : NetworkSid */
/* Purpose : Returns SID of group that includes all users logged on across */
/* a network */
/******************************************************************************/
/***/
PSID NetworkSid ( void ) {
return predefinedSIDs[ SID_NETWORK ];
} /* end NetworkSid */
/***/
/******************************************************************************/
/* Function : LocalSid */
/* Purpose : Returns SID of group that includes all users logged on locally*/
/******************************************************************************/
/***/
PSID LocalSid ( void ) {
return predefinedSIDs[ SID_LOCAL ];
} /* end LocalSid */
/***/
/******************************************************************************/
/* Function : DialupSid */
/* Purpose : Returns SID of group that includes all users logged on to */
/* terminals using a dialup modem */
/******************************************************************************/
/***/
PSID DialupSid ( void ) {
return predefinedSIDs[ SID_DIALUP ];
} /* end DialupSid */
/***/
/******************************************************************************/
/* Function : BatchSid */
/* Purpose : Returns SID of group that includes all users logged on using */
/* a batch queue facility */
/******************************************************************************/
/***/
PSID BatchSid ( void ) {
return predefinedSIDs[ SID_BATCH ];
} /* end BatchSid */
/***/
/******************************************************************************/
/* Function : CreatorOwnerSid */
/* Purpose : Returns SID of 'CREATOR OWNER' special group */
/******************************************************************************/
/***/
PSID CreatorOwnerSid ( void ) {
return predefinedSIDs[ SID_CREATOR_OWNER ];
} /* end CreatorOwnerSid */
/***/
/******************************************************************************/
/* Function : NullSid */
/* Purpose : Returns null SID */
/******************************************************************************/
/***/
PSID NullSid ( void ) {
return predefinedSIDs[ SID_NULL ];
} /* end NullSid */
/***/
/******************************************************************************/
/* Function : GetFileSecurityEx */
/* Purpose : Allocates a security descriptor and fills it out by security */
/* information which belongs to the specified file */
/* Returns : Pointer to the allocated security descriptor on success */
/* NULL otherwise */
/* Warning : Allocated security descriptor must be deallocated by */
/* 'FreeFileSecurity' function */
/******************************************************************************/
/***/
#if defined(__CYGWIN32__) || defined(__MINGW32__)
#define __try
#define __finally
#define __leave return retVal
#endif
PSECURITY_DESCRIPTOR GetFileSecurityEx ( LPCWSTR fileName, SECURITY_INFORMATION si ) {
DWORD errVal;
DWORD dwSize;
DWORD dwSizeNeeded = 0;
PSECURITY_DESCRIPTOR retVal = NULL;
BOOL fOK = FALSE;
__try {
do {
dwSize = dwSizeNeeded;
errVal = ERROR_SUCCESS;
if ( !GetFileSecurityW (
fileName, si,
retVal, dwSize, &dwSizeNeeded
)
) {
if ( ( errVal = GetLastError () ) != ERROR_INSUFFICIENT_BUFFER ) __leave;
if ( ( retVal = ( PSECURITY_DESCRIPTOR )HeapAlloc ( hHeap, 0, dwSizeNeeded )
) == NULL
) __leave;
} /* end if */
} while ( errVal != ERROR_SUCCESS );
fOK = TRUE;
} /* end __try */
__finally {
if ( !fOK && retVal != NULL ) {
HeapFree ( hHeap, 0, retVal );
retVal = NULL;
} /* end if */
} /* end __finally */
#ifdef VAC
leave: ; // added for VisualAge
#endif
return retVal;
} /* end GetFileSecurityEx */
#if defined(__CYGWIN32__) || defined(__MINGW32__)
#undef __try
#undef __finally
#undef __leave
#endif
/***/
/******************************************************************************/
/* Function : FreeFileSecurity */
/* Purpose : Deallocates security descriptor which was allocated by the */
/* 'GetFileSecurityEx' function */
/******************************************************************************/
/***/
void FreeFileSecurity ( PSECURITY_DESCRIPTOR pSD ) {
HeapFree ( hHeap, 0, ( LPVOID )pSD );
} /* end FreeFileSecurity */
/******************************************************************************/
/* Function : CreateAcl */
/* Purpose : Allocates and initializes access-control list */
/* Returns : Pointer to the allocated and initialized ACL on success, */
/* NULL otherwise */
/* Warning : Allocated ACL must be deallocated by 'FreeAcl' function */
/******************************************************************************/
/***/
PACL CreateAcl ( DWORD dwAclSize ) {
PACL retVal;
retVal = ( PACL )HeapAlloc ( hHeap, 0, dwAclSize );
if ( retVal != NULL )
InitializeAcl ( retVal, dwAclSize, ACL_REVISION );
return retVal;
} /* end CreateAcl */
/***/
/******************************************************************************/
/* Function : FreeAcl */
/* Purpose : Deallocates access-control list which was allocated by the */
/* 'CreateAcl' function */
/******************************************************************************/
/***/
void FreeAcl ( PACL pACL ) {
HeapFree ( hHeap, 0, ( PVOID )pACL );
} /* end FreeAcl */
/******************************************************************************/
/* Function : AllocAccessAllowedAce */
/* Purpose : Allocates and initializes access-control entry */
/* Returns : Pointer to the ACE on success, NULL othrwise */
/* Warning : Allocated ACE must be deallocated by the 'FreeAce' function */
/******************************************************************************/
/***/
PVOID AllocAccessAllowedAce ( DWORD dwMask, BYTE flags, PSID pSID ) {
PFILE_ACE retVal;
WORD wSize;
wSize = (WORD)( sizeof ( ACE_HEADER ) + sizeof ( DWORD ) + GetLengthSid ( pSID ) );
retVal = ( PFILE_ACE )HeapAlloc ( hHeap, 0, wSize );
if ( retVal != NULL ) {
retVal -> header.AceType = ACCESS_ALLOWED_ACE_TYPE;
retVal -> header.AceFlags = flags;
retVal -> header.AceSize = wSize;
retVal -> dwMask = dwMask;
CopySid ( GetLengthSid ( pSID ), &retVal -> pSID, pSID );
} /* end if */
return retVal;
} /* end AllocAccessAllowedAce */
/***/
/******************************************************************************/
/* Function : FreeAce */
/* Purpose : Deallocates an ACE which was allocated by the */
/* 'AllocAccessAllowedAce ' function */
/******************************************************************************/
/***/
void FreeAce ( PVOID pACE ) {
HeapFree ( hHeap, 0, pACE );
} /* end FreeAce */
#endif
#define WILD_CARD L"/*.*"
#define WILD_CARD_LEN ( sizeof ( WILD_CARD ) )
/***/
/******************************************************************************/
/* Function : MoveDirectory */
/* Purpose : Moves specified directory tree to the new location */
/* Returns : TRUE on success, FALSE otherwise */
/******************************************************************************/
/***/
static BOOL MoveDirectory ( LPCWSTR oldDir, LPCWSTR newDir, DWORD& theRecurseLevel ) {
PWIN32_FIND_DATAW pFD;
LPWSTR pName;
LPWSTR pFullNameSrc;
LPWSTR pFullNameDst;
LPWSTR driveSrc, driveDst;
LPWSTR pathSrc, pathDst;
HANDLE hFindFile;
BOOL fFind;
BOOL retVal = FALSE;
DIR_RESPONSE response;
if (theRecurseLevel == 0) {
++theRecurseLevel;
fFind = FALSE;
driveSrc = driveDst = pathSrc = pathDst = NULL;
if ( ( driveSrc = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DRIVE * sizeof(WCHAR) ) ) != NULL &&
( driveDst = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DRIVE * sizeof(WCHAR) ) ) != NULL &&
( pathSrc = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DIR * sizeof(WCHAR) ) ) != NULL &&
( pathDst = ( LPWSTR )HeapAlloc ( hHeap, 0, _MAX_DIR * sizeof(WCHAR) ) ) != NULL
) {
_wsplitpath ( oldDir, driveSrc, pathSrc, NULL, NULL );
_wsplitpath ( newDir, driveDst, pathDst, NULL, NULL );
if ( wcscmp ( driveSrc, driveDst ) == 0 &&
wcscmp ( pathSrc, pathDst ) == 0
) {
retry:
retVal = MoveFileExW (
oldDir, newDir, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
);
fFind = TRUE;
if ( !retVal ) {
if ( _response_dir_proc != NULL ) {
response = ( *_response_dir_proc ) ( oldDir );
if ( response == DIR_RETRY )
goto retry;
else if ( response == DIR_IGNORE )
retVal = TRUE;
} /* end if */
} else if ( _move_dir_proc != NULL )
( *_move_dir_proc ) ( oldDir, newDir );
} /* end if */
} /* end if */
if ( pathDst != NULL ) HeapFree ( hHeap, 0, pathDst );
if ( pathSrc != NULL ) HeapFree ( hHeap, 0, pathSrc );
if ( driveDst != NULL ) HeapFree ( hHeap, 0, driveDst );
if ( driveSrc != NULL ) HeapFree ( hHeap, 0, driveSrc );
if ( fFind ) {
--theRecurseLevel;
return retVal;
} // end if
} else {
++theRecurseLevel;
} // end else
pFD = NULL;
pName = NULL;
pFullNameSrc = pFullNameDst = NULL;
hFindFile = INVALID_HANDLE_VALUE;
retVal = FALSE;
retVal = CreateDirectoryW ( newDir, NULL );
if ( retVal || ( !retVal && GetLastError () == ERROR_ALREADY_EXISTS ) ) {
size_t anOldDirLength;
StringCchLengthW (oldDir, sizeof(oldDir) / sizeof(oldDir[0]), &anOldDirLength);
if ( ( pFD = ( PWIN32_FIND_DATAW )HeapAlloc (
hHeap, 0, sizeof ( WIN32_FIND_DATAW )
)
) != NULL &&
(
pName = (LPWSTR)HeapAlloc(
hHeap, 0, anOldDirLength + WILD_CARD_LEN +
sizeof(L'\x00')
)
) != NULL
) {
StringCchCopyW (pName, sizeof(pName) / sizeof(pName[0]), oldDir);
StringCchCatW (pName, sizeof(pName), WILD_CARD);
retVal = TRUE;
fFind = ( hFindFile = FindFirstFileExW(pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0) ) != INVALID_HANDLE_VALUE;
while ( fFind ) {
if ( pFD -> cFileName[ 0 ] != L'.' ||
pFD -> cFileName[ 0 ] != L'.' &&
pFD -> cFileName[ 1 ] != L'.'
) {
size_t anOldDirLength2;
size_t aNewDirLength;
size_t aFileNameLength;
StringCchLengthW (oldDir, sizeof(oldDir) / sizeof(oldDir[0]), &anOldDirLength2);
StringCchLengthW (newDir, sizeof(newDir) / sizeof(newDir[0]), &aNewDirLength);
StringCchLengthW (pFD->cFileName, sizeof(pFD->cFileName) / sizeof(pFD->cFileName[0]), &aFileNameLength);
if ( (pFullNameSrc = (LPWSTR)HeapAlloc(
hHeap, 0,
anOldDirLength2 + aFileNameLength +
sizeof(L'/') + sizeof(L'\x00')
)
) == NULL ||
(pFullNameDst = (LPWSTR)HeapAlloc(
hHeap, 0,
aNewDirLength + aFileNameLength +
sizeof(L'/') + sizeof(L'\x00')
)
) == NULL
) break;
StringCchCopyW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), oldDir);
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), L"/");
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), pFD->cFileName);
StringCchCopyW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), newDir);
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), L"/");
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), pFD->cFileName);
if ( pFD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
retVal = MoveDirectory ( pFullNameSrc, pFullNameDst, theRecurseLevel );
if (!retVal) break;
} else {
retry_1:
retVal = MoveFileExW (pFullNameSrc, pFullNameDst,
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
if (! retVal) {
if ( _response_dir_proc != NULL ) {
response = ( *_response_dir_proc ) ( pFullNameSrc );
if ( response == DIR_ABORT )
break;
else if ( response == DIR_RETRY )
goto retry_1;
else if ( response == DIR_IGNORE )
retVal = TRUE;
else
break;
} /* end if */
} else if ( _move_dir_proc != NULL )
( *_move_dir_proc ) ( pFullNameSrc, pFullNameDst );
} /* end else */
HeapFree ( hHeap, 0, pFullNameDst );
HeapFree ( hHeap, 0, pFullNameSrc );
pFullNameSrc = pFullNameDst = NULL;
} /* end if */
fFind = FindNextFileW ( hFindFile, pFD );
} /* end while */
} /* end if */
} /* end if ( error creating directory ) */
if ( hFindFile != INVALID_HANDLE_VALUE ) FindClose ( hFindFile );
if ( pFullNameSrc != NULL ) HeapFree ( hHeap, 0, pFullNameSrc );
if ( pFullNameDst != NULL ) HeapFree ( hHeap, 0, pFullNameDst );
if ( pName != NULL ) HeapFree ( hHeap, 0, pName );
if ( pFD != NULL ) HeapFree ( hHeap, 0, pFD );
if ( retVal ) {
retry_2:
retVal = RemoveDirectoryW ( oldDir );
if ( !retVal ) {
if ( _response_dir_proc != NULL ) {
response = ( *_response_dir_proc ) ( oldDir );
if ( response == DIR_RETRY )
goto retry_2;
else if ( response == DIR_IGNORE )
retVal = TRUE;
} /* end if */
} /* end if */
} /* end if */
--theRecurseLevel;
return retVal;
} /* end MoveDirectory */
BOOL MoveDirectory (LPCWSTR oldDir, LPCWSTR newDir)
{
DWORD aRecurseLevel = 0;
return MoveDirectory (oldDir, newDir, aRecurseLevel);
}
/***/
/******************************************************************************/
/* Function : CopyDirectory */
/* Purpose : Copies specified directory tree to the new location */
/* Returns : TRUE on success, FALSE otherwise */
/******************************************************************************/
/***/
BOOL CopyDirectory ( LPCWSTR dirSrc, LPCWSTR dirDst ) {
PWIN32_FIND_DATAW pFD = NULL;
LPWSTR pName = NULL;
LPWSTR pFullNameSrc = NULL;
LPWSTR pFullNameDst = NULL;
HANDLE hFindFile = INVALID_HANDLE_VALUE;
BOOL fFind;
BOOL retVal = FALSE;
DIR_RESPONSE response;
retVal = CreateDirectoryW ( dirDst, NULL );
if ( retVal || ( !retVal && GetLastError () == ERROR_ALREADY_EXISTS ) ) {
size_t aDirSrcLength;
StringCchLengthW (dirSrc, sizeof(dirSrc) / sizeof(dirSrc[0]), &aDirSrcLength);
if ( ( pFD = ( PWIN32_FIND_DATAW )HeapAlloc (
hHeap, 0, sizeof ( WIN32_FIND_DATAW )
)
) != NULL &&
( pName = ( LPWSTR )HeapAlloc (
hHeap, 0, aDirSrcLength + WILD_CARD_LEN +
sizeof ( L'\x00' )
)
) != NULL
) {
StringCchCopyW (pName, sizeof(pName) / sizeof(pName[0]), dirSrc);
StringCchCatW (pName, sizeof(pName) / sizeof(pName[0]), WILD_CARD);
retVal = TRUE;
fFind = (hFindFile = FindFirstFileExW(pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0)) != INVALID_HANDLE_VALUE;
while ( fFind ) {
if ( pFD -> cFileName[ 0 ] != L'.' ||
pFD -> cFileName[ 0 ] != L'.' &&
pFD -> cFileName[ 1 ] != L'.'
) {
size_t aDirSrcLength2;
size_t aDirDstLength;
size_t aFileNameLength;
StringCchLengthW (dirSrc, sizeof(dirSrc) / sizeof(dirSrc[0]), &aDirSrcLength2);
StringCchLengthW (dirDst, sizeof(dirDst) / sizeof(dirDst[0]), &aDirDstLength);
StringCchLengthW (pFD -> cFileName, sizeof(pFD -> cFileName) / sizeof(pFD -> cFileName[0]), &aFileNameLength);
if ( ( pFullNameSrc = ( LPWSTR )HeapAlloc (
hHeap, 0,
aDirSrcLength2 + aFileNameLength +
sizeof ( L'/' ) + sizeof ( L'\x00' )
)
) == NULL ||
( pFullNameDst = ( LPWSTR )HeapAlloc (
hHeap, 0,
aDirDstLength + aFileNameLength +
sizeof ( L'/' ) + sizeof ( L'\x00' )
)
) == NULL
) break;
StringCchCopyW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), dirSrc);
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), L"/");
StringCchCatW (pFullNameSrc, sizeof(pFullNameSrc) / sizeof(pFullNameSrc[0]), pFD->cFileName);
StringCchCopyW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), dirDst);
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), L"/");
StringCchCatW (pFullNameDst, sizeof(pFullNameDst) / sizeof(pFullNameDst[0]), pFD->cFileName);
if ( pFD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
retVal = CopyDirectory ( pFullNameSrc, pFullNameDst );
if ( ! retVal ) break;
} else {
retry:
#ifndef OCCT_UWP
retVal = CopyFileW(pFullNameSrc, pFullNameDst, FALSE);
#else
retVal = (CopyFile2(pFullNameSrc, pFullNameDst, FALSE) == S_OK) ? TRUE : FALSE;
#endif
if ( ! retVal ) {
if ( _response_dir_proc != NULL ) {
response = ( *_response_dir_proc ) ( pFullNameSrc );
if ( response == DIR_ABORT )
break;
else if ( response == DIR_RETRY )
goto retry;
else if ( response == DIR_IGNORE )
retVal = TRUE;
else
break;
} /* end if */
} else if ( _copy_dir_proc != NULL )
( *_copy_dir_proc ) ( pFullNameSrc, pFullNameDst );
} /* end else */
HeapFree ( hHeap, 0, pFullNameDst );
HeapFree ( hHeap, 0, pFullNameSrc );
pFullNameSrc = pFullNameDst = NULL;
} /* end if */
fFind = FindNextFileW ( hFindFile, pFD );
} /* end while */
} /* end if */
} /* end if ( error creating directory ) */
if ( hFindFile != INVALID_HANDLE_VALUE ) FindClose ( hFindFile );
if ( pFullNameSrc != NULL ) HeapFree ( hHeap, 0, pFullNameSrc );
if ( pFullNameDst != NULL ) HeapFree ( hHeap, 0, pFullNameDst );
if ( pName != NULL ) HeapFree ( hHeap, 0, pName );
if ( pFD != NULL ) HeapFree ( hHeap, 0, pFD );
return retVal;
} /* end CopyDirectory */
/***/
/******************************************************************************/
/* Function : SetMoveDirectoryProc */
/* Purpose : Sets callback procedure which is calling by the */
/* 'MoveDirectory' after moving of each item in the */
/* directory. To unregister this callback function supply NULL */
/* pointer */
/******************************************************************************/
/***/
void SetMoveDirectoryProc ( MOVE_DIR_PROC proc ) {
_move_dir_proc = proc;
} /* end SetMoveDirectoryProc */
/***/
/******************************************************************************/
/* Function : SetCopyDirectoryProc */
/* Purpose : Sets callback procedure which is calling by the */
/* 'CopyDirectory' after copying of each item in the */
/* directory. To unregister this callback function supply NULL */
/* pointer */
/******************************************************************************/
/***/
void SetCopyDirectoryProc ( COPY_DIR_PROC proc ) {
_copy_dir_proc = proc;
} /* end SetCopyDirectoryProc */
/***/
/******************************************************************************/
/* Function : SetResponseDirectoryProc */
/* Purpose : Sets callback procedure which is calling by the */
/* directoy processing function if an error was occur. */
/* The return value of that callback procedure determines */
/* behaviour of directoy processing functions in case of error. */
/* To unregister this callback function supply NULL pointer */
/******************************************************************************/
/***/
void SetResponseDirectoryProc ( RESPONSE_DIR_PROC proc ) {
_response_dir_proc = proc;
} /* end SetResponseDirectoryProc */
/***/
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
#endif