mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
Reorganizing structure to have Module/TK/Package/FILES structure. New structure reflect the structure inside IDE. Migrate FILES, PACKAGES, EXTRLIB to CMake version to handle changes on updates. No changes were done to installation layout, all installation result keep as before. The migration was done using python script, see PR, which refactor automatically the structure. Updated doc generation to have valid path to modules, toolkits and packages. In case of PR into new version, IR-790 can be used as a target for the previous version.
1141 lines
35 KiB
C++
1141 lines
35 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 convenient than WIN32 */
|
|
/* ones ) and other convrnient functions. */
|
|
/******************************************************************************/
|
|
/***/
|
|
#include <OSD_WNT.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(const wchar_t* oldDir, const wchar_t* newDir, DWORD& theRecurseLevel)
|
|
{
|
|
wchar_t* driveSrc = NULL;
|
|
wchar_t* driveDst = NULL;
|
|
wchar_t* pathSrc = NULL;
|
|
wchar_t* pathDst = NULL;
|
|
BOOL retVal = FALSE;
|
|
if (theRecurseLevel == 0)
|
|
{
|
|
++theRecurseLevel;
|
|
BOOL fFind = FALSE;
|
|
if ((driveSrc = (wchar_t*)HeapAlloc(hHeap, 0, _MAX_DRIVE * sizeof(wchar_t))) != NULL
|
|
&& (driveDst = (wchar_t*)HeapAlloc(hHeap, 0, _MAX_DRIVE * sizeof(wchar_t))) != NULL
|
|
&& (pathSrc = (wchar_t*)HeapAlloc(hHeap, 0, _MAX_DIR * sizeof(wchar_t))) != NULL
|
|
&& (pathDst = (wchar_t*)HeapAlloc(hHeap, 0, _MAX_DIR * sizeof(wchar_t))) != 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)
|
|
{
|
|
const DIR_RESPONSE response = _response_dir_proc(oldDir);
|
|
if (response == DIR_RETRY)
|
|
{
|
|
goto retry;
|
|
}
|
|
else if (response == DIR_IGNORE)
|
|
{
|
|
retVal = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else if (_move_dir_proc != NULL)
|
|
{
|
|
_move_dir_proc(oldDir, newDir);
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
++theRecurseLevel;
|
|
}
|
|
|
|
WIN32_FIND_DATAW* pFD = NULL;
|
|
wchar_t* pName = NULL;
|
|
wchar_t* pFullNameSrc = NULL;
|
|
wchar_t* pFullNameDst = NULL;
|
|
HANDLE hFindFile = INVALID_HANDLE_VALUE;
|
|
retVal = CreateDirectoryW(newDir, NULL);
|
|
if (retVal || (!retVal && GetLastError() == ERROR_ALREADY_EXISTS))
|
|
{
|
|
size_t anOldDirLength;
|
|
StringCchLengthW(oldDir, MAX_PATH, &anOldDirLength);
|
|
const size_t aNameLength = anOldDirLength + WILD_CARD_LEN + sizeof(L'\x00');
|
|
if ((pFD = (WIN32_FIND_DATAW*)HeapAlloc(hHeap, 0, sizeof(WIN32_FIND_DATAW))) != NULL
|
|
&& (pName = (wchar_t*)HeapAlloc(hHeap, 0, aNameLength)) != NULL)
|
|
{
|
|
StringCchCopyW(pName, aNameLength, oldDir);
|
|
StringCchCatW(pName, aNameLength, WILD_CARD);
|
|
retVal = TRUE;
|
|
hFindFile = FindFirstFileExW(pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0);
|
|
for (BOOL fFind = hFindFile != INVALID_HANDLE_VALUE; fFind;
|
|
fFind = FindNextFileW(hFindFile, pFD))
|
|
{
|
|
if ((pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'\0')
|
|
|| (pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'.'
|
|
&& pFD->cFileName[2] == L'\0'))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
size_t aNewDirLength = 0, aFileNameLength = 0;
|
|
StringCchLengthW(newDir, MAX_PATH, &aNewDirLength);
|
|
StringCchLengthW(pFD->cFileName,
|
|
sizeof(pFD->cFileName) / sizeof(pFD->cFileName[0]),
|
|
&aFileNameLength);
|
|
const size_t aFullNameSrcLength =
|
|
anOldDirLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00');
|
|
const size_t aFullNameDstLength =
|
|
aNewDirLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00');
|
|
if ((pFullNameSrc = (wchar_t*)HeapAlloc(hHeap, 0, aFullNameSrcLength)) == NULL
|
|
|| (pFullNameDst = (wchar_t*)HeapAlloc(hHeap, 0, aFullNameDstLength)) == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
StringCchCopyW(pFullNameSrc, aFullNameSrcLength, oldDir);
|
|
StringCchCatW(pFullNameSrc, aFullNameSrcLength, L"/");
|
|
StringCchCatW(pFullNameSrc, aFullNameSrcLength, pFD->cFileName);
|
|
|
|
StringCchCopyW(pFullNameDst, aFullNameDstLength, newDir);
|
|
StringCchCatW(pFullNameDst, aFullNameDstLength, L"/");
|
|
StringCchCatW(pFullNameDst, aFullNameDstLength, pFD->cFileName);
|
|
|
|
if ((pFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
|
{
|
|
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)
|
|
{
|
|
const DIR_RESPONSE 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;
|
|
}
|
|
}
|
|
}
|
|
else if (_move_dir_proc != NULL)
|
|
{
|
|
_move_dir_proc(pFullNameSrc, pFullNameDst);
|
|
}
|
|
}
|
|
|
|
HeapFree(hHeap, 0, pFullNameDst);
|
|
HeapFree(hHeap, 0, pFullNameSrc);
|
|
pFullNameSrc = pFullNameDst = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
const DIR_RESPONSE response = _response_dir_proc(oldDir);
|
|
if (response == DIR_RETRY)
|
|
{
|
|
goto retry_2;
|
|
}
|
|
else if (response == DIR_IGNORE)
|
|
{
|
|
retVal = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
--theRecurseLevel;
|
|
return retVal;
|
|
}
|
|
|
|
BOOL MoveDirectory(const wchar_t* oldDir, const wchar_t* 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(const wchar_t* dirSrc, const wchar_t* dirDst)
|
|
{
|
|
WIN32_FIND_DATAW* pFD = NULL;
|
|
wchar_t* pName = NULL;
|
|
wchar_t* pFullNameSrc = NULL;
|
|
wchar_t* pFullNameDst = NULL;
|
|
HANDLE hFindFile = INVALID_HANDLE_VALUE;
|
|
|
|
BOOL retVal = CreateDirectoryW(dirDst, NULL);
|
|
if (retVal || (!retVal && GetLastError() == ERROR_ALREADY_EXISTS))
|
|
{
|
|
size_t aDirSrcLength = 0;
|
|
StringCchLengthW(dirSrc, MAX_PATH, &aDirSrcLength);
|
|
const size_t aNameLength = aDirSrcLength + WILD_CARD_LEN + sizeof(L'\x00');
|
|
if ((pFD = (WIN32_FIND_DATAW*)HeapAlloc(hHeap, 0, sizeof(WIN32_FIND_DATAW))) != NULL
|
|
&& (pName = (wchar_t*)HeapAlloc(hHeap, 0, aNameLength)) != NULL)
|
|
{
|
|
StringCchCopyW(pName, aNameLength, dirSrc);
|
|
StringCchCatW(pName, aNameLength, WILD_CARD);
|
|
|
|
retVal = TRUE;
|
|
hFindFile = FindFirstFileExW(pName, FindExInfoStandard, pFD, FindExSearchNameMatch, NULL, 0);
|
|
for (BOOL fFind = hFindFile != INVALID_HANDLE_VALUE; fFind;
|
|
fFind = FindNextFileW(hFindFile, pFD))
|
|
{
|
|
if ((pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'\0')
|
|
|| (pFD->cFileName[0] == L'.' && pFD->cFileName[1] == L'.'
|
|
&& pFD->cFileName[2] == L'\0'))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
size_t aDirDstLength = 0, aFileNameLength = 0;
|
|
StringCchLengthW(dirDst, MAX_PATH, &aDirDstLength);
|
|
StringCchLengthW(pFD->cFileName,
|
|
sizeof(pFD->cFileName) / sizeof(pFD->cFileName[0]),
|
|
&aFileNameLength);
|
|
const size_t aFullNameSrcLength =
|
|
aDirSrcLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00');
|
|
const size_t aFullNameDstLength =
|
|
aDirDstLength + aFileNameLength + sizeof(L'/') + sizeof(L'\x00');
|
|
if ((pFullNameSrc = (wchar_t*)HeapAlloc(hHeap, 0, aFullNameSrcLength)) == NULL
|
|
|| (pFullNameDst = (wchar_t*)HeapAlloc(hHeap, 0, aFullNameDstLength)) == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
StringCchCopyW(pFullNameSrc, aFullNameSrcLength, dirSrc);
|
|
StringCchCatW(pFullNameSrc, aFullNameSrcLength, L"/");
|
|
StringCchCatW(pFullNameSrc, aFullNameSrcLength, pFD->cFileName);
|
|
|
|
StringCchCopyW(pFullNameDst, aFullNameDstLength, dirDst);
|
|
StringCchCatW(pFullNameDst, aFullNameDstLength, L"/");
|
|
StringCchCatW(pFullNameDst, aFullNameDstLength, pFD->cFileName);
|
|
if ((pFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
|
{
|
|
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)
|
|
{
|
|
const DIR_RESPONSE 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;
|
|
}
|
|
}
|
|
}
|
|
else if (_copy_dir_proc != NULL)
|
|
{
|
|
_copy_dir_proc(pFullNameSrc, pFullNameDst);
|
|
}
|
|
}
|
|
|
|
HeapFree(hHeap, 0, pFullNameDst);
|
|
HeapFree(hHeap, 0, pFullNameSrc);
|
|
pFullNameSrc = pFullNameDst = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
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 */
|
|
/* directory processing function if an error was occur. */
|
|
/* The return value of that callback procedure determines */
|
|
/* behaviour of directory 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
|