diff options
author | XhmikosR <xhmikosr@gmail.com> | 2015-02-02 19:20:50 +0300 |
---|---|---|
committer | XhmikosR <xhmikosr@gmail.com> | 2015-02-17 00:30:36 +0300 |
commit | b42b48edf2dfa3767a80d56ac1e9e9255ab78151 (patch) | |
tree | 607cc60a08c54fd54170d3520f863452965023ee /src/thirdparty/unrar | |
parent | 98c02856528b848b5c286176585c2599910ded58 (diff) |
Update Unrar to v5.2.6.
Diffstat (limited to 'src/thirdparty/unrar')
-rw-r--r-- | src/thirdparty/unrar/arcread.cpp | 3 | ||||
-rw-r--r-- | src/thirdparty/unrar/cmddata.cpp | 11 | ||||
-rw-r--r-- | src/thirdparty/unrar/cmddata.hpp | 3 | ||||
-rw-r--r-- | src/thirdparty/unrar/dll.rc | 8 | ||||
-rw-r--r-- | src/thirdparty/unrar/extinfo.cpp | 35 | ||||
-rw-r--r-- | src/thirdparty/unrar/extinfo.hpp | 1 | ||||
-rw-r--r-- | src/thirdparty/unrar/extract.cpp | 42 | ||||
-rw-r--r-- | src/thirdparty/unrar/file.cpp | 8 | ||||
-rw-r--r-- | src/thirdparty/unrar/file.hpp | 2 | ||||
-rw-r--r-- | src/thirdparty/unrar/loclang.hpp | 2 | ||||
-rw-r--r-- | src/thirdparty/unrar/options.hpp | 1 | ||||
-rw-r--r-- | src/thirdparty/unrar/pathfn.cpp | 8 | ||||
-rw-r--r-- | src/thirdparty/unrar/pathfn.hpp | 1 | ||||
-rw-r--r-- | src/thirdparty/unrar/ulinks.cpp | 16 | ||||
-rw-r--r-- | src/thirdparty/unrar/version.hpp | 6 | ||||
-rw-r--r-- | src/thirdparty/unrar/win32lnk.cpp | 37 |
16 files changed, 124 insertions, 60 deletions
diff --git a/src/thirdparty/unrar/arcread.cpp b/src/thirdparty/unrar/arcread.cpp index e8e5991da..047289b7a 100644 --- a/src/thirdparty/unrar/arcread.cpp +++ b/src/thirdparty/unrar/arcread.cpp @@ -886,7 +886,8 @@ void Archive::RequestArcPassword() ErrHandler.Exit(RARX_USERBREAK); } #else - if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password)) + if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password) || + !Cmd->Password.IsSet()) { Close(); uiMsg(UIERROR_INCERRCOUNT); diff --git a/src/thirdparty/unrar/cmddata.cpp b/src/thirdparty/unrar/cmddata.cpp index b56410ae9..3f84cc373 100644 --- a/src/thirdparty/unrar/cmddata.cpp +++ b/src/thirdparty/unrar/cmddata.cpp @@ -616,6 +616,8 @@ void CommandData::ProcessSwitch(const wchar *Switch) #ifdef SAVE_LINKS case 'L': SaveSymLinks=true; + if (toupperw(Switch[2])=='A') + AbsoluteLinks=true; break; #endif case 'R': @@ -958,7 +960,7 @@ void CommandData::OutHelp(RAR_EXIT ExitCode) MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU, MCHelpSwDH,MCHelpSwEP,MCHelpSwEP3,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR, MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal, - MCHelpSwO,MCHelpSwOC,MCHelpSwOR,MCHelpSwOW,MCHelpSwP, + MCHelpSwO,MCHelpSwOC,MCHelpSwOL,MCHelpSwOR,MCHelpSwOW,MCHelpSwP, MCHelpSwPm,MCHelpSwR,MCHelpSwRI,MCHelpSwSC,MCHelpSwSL,MCHelpSwSM, MCHelpSwTA,MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU, MCHelpSwVUnr,MCHelpSwVER,MCHelpSwVP,MCHelpSwX,MCHelpSwXa,MCHelpSwXal, @@ -1157,8 +1159,11 @@ bool CommandData::SizeCheck(int64 Size) -int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType) +int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType, + wchar *MatchedArg,uint MatchedArgSize) { + if (MatchedArg!=NULL && MatchedArgSize>0) + *MatchedArg=0; if (wcslen(FileHead.FileName)>=NM) return 0; bool Dir=FileHead.Dir; @@ -1179,6 +1184,8 @@ int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchTy { if (ExactMatch!=NULL) *ExactMatch=wcsicompc(ArgName,FileHead.FileName)==0; + if (MatchedArg!=NULL) + wcsncpyz(MatchedArg,ArgName,MatchedArgSize); return StringCount; } return 0; diff --git a/src/thirdparty/unrar/cmddata.hpp b/src/thirdparty/unrar/cmddata.hpp index 3ed4ef1d8..d2cdbb94d 100644 --- a/src/thirdparty/unrar/cmddata.hpp +++ b/src/thirdparty/unrar/cmddata.hpp @@ -37,7 +37,8 @@ class CommandData:public RAROptions bool TimeCheck(RarTime &ft); bool SizeCheck(int64 Size); bool AnyFiltersActive(); - int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH); + int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH, + wchar *MatchedArg=NULL,uint MatchedArgSize=0); void ProcessCommand(); void AddArcName(const wchar *Name); bool GetArcName(wchar *Name,int MaxSize); diff --git a/src/thirdparty/unrar/dll.rc b/src/thirdparty/unrar/dll.rc index 3c90c69cb..7de848921 100644 --- a/src/thirdparty/unrar/dll.rc +++ b/src/thirdparty/unrar/dll.rc @@ -2,8 +2,8 @@ #include <commctrl.h>
VS_VERSION_INFO VERSIONINFO
-FILEVERSION 5, 21, 1, 1472
-PRODUCTVERSION 5, 21, 1, 1472
+FILEVERSION 5, 21, 100, 1509
+PRODUCTVERSION 5, 21, 100, 1509
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
@@ -14,8 +14,8 @@ FILETYPE VFT_APP VALUE "CompanyName", "Alexander Roshal\0"
VALUE "ProductName", "RAR decompression library\0"
VALUE "FileDescription", "RAR decompression library\0"
- VALUE "FileVersion", "5.21.1\0"
- VALUE "ProductVersion", "5.21.1\0"
+ VALUE "FileVersion", "5.21.0\0"
+ VALUE "ProductVersion", "5.21.0\0"
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2015\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
diff --git a/src/thirdparty/unrar/extinfo.cpp b/src/thirdparty/unrar/extinfo.cpp index 141967f2a..01827eba0 100644 --- a/src/thirdparty/unrar/extinfo.cpp +++ b/src/thirdparty/unrar/extinfo.cpp @@ -60,14 +60,45 @@ void SetExtraInfo(CommandData *Cmd,Archive &Arc,wchar *Name) +bool IsRelativeSymlinkSafe(const wchar *SrcName,const wchar *TargetName) +{ + if (IsFullRootPath(SrcName)) + return false; + int AllowedDepth=0; + while (*SrcName!=0) + { + if (IsPathDiv(SrcName[0]) && SrcName[1]!=0 && !IsPathDiv(SrcName[1])) + { + bool Dot=SrcName[1]=='.' && (IsPathDiv(SrcName[2]) || SrcName[2]==0); + bool Dot2=SrcName[1]=='.' && SrcName[2]=='.' && (IsPathDiv(SrcName[3]) || SrcName[3]==0); + if (!Dot && !Dot2) + AllowedDepth++; + } + SrcName++; + } + if (IsFullRootPath(TargetName)) // Catch root dir based /path/file paths. + return false; + for (int Pos=0;*TargetName!=0;Pos++) + { + bool Dot2=TargetName[0]=='.' && TargetName[1]=='.' && + (IsPathDiv(TargetName[2]) || TargetName[2]==0) && + (Pos==0 || IsPathDiv(*(TargetName-1))); + if (Dot2) + AllowedDepth--; + TargetName++; + } + return AllowedDepth>=0; +} + + bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName) { #if defined(SAVE_LINKS) && defined(_UNIX) // For RAR 3.x archives we process links even in test mode to skip link data. if (Arc.Format==RARFMT15) - return ExtractUnixLink30(DataIO,Arc,LinkName); + return ExtractUnixLink30(Cmd,DataIO,Arc,LinkName); if (Arc.Format==RARFMT50) - return ExtractUnixLink50(LinkName,&Arc.FileHead); + return ExtractUnixLink50(Cmd,LinkName,&Arc.FileHead); #elif defined _WIN_ALL // RAR 5.0 archives store link information in file header, so there is // no need to additionally test it if we do not create a file. diff --git a/src/thirdparty/unrar/extinfo.hpp b/src/thirdparty/unrar/extinfo.hpp index 224564da8..b974bf489 100644 --- a/src/thirdparty/unrar/extinfo.hpp +++ b/src/thirdparty/unrar/extinfo.hpp @@ -1,6 +1,7 @@ #ifndef _RAR_EXTINFO_ #define _RAR_EXTINFO_ +bool IsRelativeSymlinkSafe(const wchar *SrcName,const wchar *TargetName); bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName); #ifdef _UNIX void SetUnixOwner(Archive &Arc,const wchar *FileName); diff --git a/src/thirdparty/unrar/extract.cpp b/src/thirdparty/unrar/extract.cpp index fb5a39d5b..26be36ac2 100644 --- a/src/thirdparty/unrar/extract.cpp +++ b/src/thirdparty/unrar/extract.cpp @@ -259,17 +259,19 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat) int MatchType=MATCH_WILDSUBPATH;
bool EqualNames=false;
- int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType);
- bool ExactMatch=MatchNumber!=0;
+ wchar MatchedArg[NM];
+ int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType,MatchedArg,ASIZE(MatchedArg));
+ bool MatchFound=MatchNumber!=0;
#ifndef SFX_MODULE
- if (*Cmd->ArcPath==0 && Cmd->ExclPath==EXCL_BASEPATH && ExactMatch)
+ if (Cmd->ExclPath==EXCL_BASEPATH)
{
- Cmd->FileArgs.Rewind();
- if (Cmd->FileArgs.GetString(Cmd->ArcPath,ASIZE(Cmd->ArcPath),MatchNumber-1))
- *PointToName(Cmd->ArcPath)=0;
+ wcsncpyz(Cmd->ArcPath,MatchedArg,ASIZE(Cmd->ArcPath));
+ *PointToName(Cmd->ArcPath)=0;
+ if (IsWildcard(Cmd->ArcPath)) // Cannot correctly process path*\* masks here.
+ *Cmd->ArcPath=0;
}
#endif
- if (ExactMatch && !EqualNames)
+ if (MatchFound && !EqualNames)
AllMatchesExact=false;
Arc.ConvertAttributes();
@@ -311,17 +313,17 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat) if (Cmd->VersionControl!=1 && !EqualNames)
{
if (Cmd->VersionControl==0)
- ExactMatch=false;
+ MatchFound=false;
int Version=ParseVersionFileName(ArcFileName,false);
if (Cmd->VersionControl-1==Version)
ParseVersionFileName(ArcFileName,true);
else
- ExactMatch=false;
+ MatchFound=false;
}
}
else
if (!Arc.IsArcDir() && Cmd->VersionControl>1)
- ExactMatch=false;
+ MatchFound=false;
DataIO.UnpVolume=Arc.FileHead.SplitAfter;
DataIO.NextVolumeMissing=false;
@@ -332,9 +334,9 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat) bool SkipSolid=false;
#ifndef SFX_MODULE
- if (FirstFile && (ExactMatch || Arc.Solid) && Arc.FileHead.SplitBefore)
+ if (FirstFile && (MatchFound || Arc.Solid) && Arc.FileHead.SplitBefore)
{
- if (ExactMatch)
+ if (MatchFound)
{
uiMsg(UIERROR_NEEDPREVVOL,Arc.FileName,ArcFileName);
#ifdef RARDLL
@@ -342,13 +344,13 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat) #endif
ErrHandler.SetErrorCode(RARX_OPEN);
}
- ExactMatch=false;
+ MatchFound=false;
}
FirstFile=false;
#endif
- if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
+ if (MatchFound || (SkipSolid=Arc.Solid)!=0)
{
// First common call of uiStartFileExtract. It is done before overwrite
// prompts, so if SkipSolid state is changed below, we'll need to make
@@ -408,13 +410,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat) #ifdef RARDLL
if (*Cmd->DllDestName!=0)
- {
wcsncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
-
-// Do we need this code?
-// if (Cmd->DllOpMode!=RAR_EXTRACT)
-// ExtrFile=false;
- }
#endif
if (!CheckUnpVer(Arc,ArcFileName))
@@ -713,7 +709,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat) }
}
}
- if (ExactMatch)
+ if (MatchFound)
MatchedArgs++;
if (DataIO.NextVolumeMissing)
return false;
@@ -884,8 +880,10 @@ bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName) {
if (!Cmd->Password.IsSet())
{
- if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password))
+ if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password) || !Cmd->Password.IsSet())
{
+ // Suppress "test is ok" message in GUI if user entered
+ // an empty password or cancelled a password prompt.
uiMsg(UIERROR_INCERRCOUNT);
return false;
diff --git a/src/thirdparty/unrar/file.cpp b/src/thirdparty/unrar/file.cpp index 8fba34adb..185474c25 100644 --- a/src/thirdparty/unrar/file.cpp +++ b/src/thirdparty/unrar/file.cpp @@ -281,10 +281,10 @@ bool File::Rename(const wchar *NewName) } -void File::Write(const void *Data,size_t Size) +bool File::Write(const void *Data,size_t Size) { if (Size==0) - return; + return true; if (HandleType==FILE_HANDLESTD) { #ifdef _WIN_ALL @@ -301,9 +301,10 @@ void File::Write(const void *Data,size_t Size) } #endif } + bool Success; while (1) { - bool Success=false; + Success=false; #ifdef _WIN_ALL DWORD Written=0; if (HandleType!=FILE_HANDLENORMAL) @@ -352,6 +353,7 @@ void File::Write(const void *Data,size_t Size) break; } LastWrite=true; + return Success; // It can return false only if AllowExceptions is disabled. } diff --git a/src/thirdparty/unrar/file.hpp b/src/thirdparty/unrar/file.hpp index 93aac89f3..0d6534ff7 100644 --- a/src/thirdparty/unrar/file.hpp +++ b/src/thirdparty/unrar/file.hpp @@ -80,7 +80,7 @@ class File bool Close(); bool Delete(); bool Rename(const wchar *NewName); - void Write(const void *Data,size_t Size); + bool Write(const void *Data,size_t Size); virtual int Read(void *Data,size_t Size); int DirectRead(void *Data,size_t Size); virtual void Seek(int64 Offset,int Method); diff --git a/src/thirdparty/unrar/loclang.hpp b/src/thirdparty/unrar/loclang.hpp index fb560713a..52bcafe92 100644 --- a/src/thirdparty/unrar/loclang.hpp +++ b/src/thirdparty/unrar/loclang.hpp @@ -99,7 +99,7 @@ #define MCHelpSwOC L"\n oc Set NTFS Compressed attribute" #define MCHelpSwOH L"\n oh Save hard links as the link instead of the file" #define MCHelpSwOI L"\n oi[0-4][:min] Save identical files as references" -#define MCHelpSwOL L"\n ol Save symbolic links as the link instead of the file" +#define MCHelpSwOL L"\n ol[a] Process symbolic links as the link [absolute paths]" #define MCHelpSwOR L"\n or Rename files automatically" #define MCHelpSwOS L"\n os Save NTFS streams" #define MCHelpSwOW L"\n ow Save or restore file owner and group" diff --git a/src/thirdparty/unrar/options.hpp b/src/thirdparty/unrar/options.hpp index ba9c0ca82..a6ec227f0 100644 --- a/src/thirdparty/unrar/options.hpp +++ b/src/thirdparty/unrar/options.hpp @@ -132,6 +132,7 @@ class RAROptions bool ProcessOwners; bool SaveSymLinks; bool SaveHardLinks; + bool AbsoluteLinks; int Priority; int SleepTime; bool KeepBroken; diff --git a/src/thirdparty/unrar/pathfn.cpp b/src/thirdparty/unrar/pathfn.cpp index bfd3b588e..b6e220eee 100644 --- a/src/thirdparty/unrar/pathfn.cpp +++ b/src/thirdparty/unrar/pathfn.cpp @@ -29,7 +29,7 @@ wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath) while (*DestPtr!=0) { const wchar *s=DestPtr; - if (s[0] && IsDriveDiv(s[1])) + if (s[0]!=0 && IsDriveDiv(s[1])) s+=2; if (s[0]=='\\' && s[1]=='\\') { @@ -541,6 +541,12 @@ bool IsFullPath(const wchar *Path) } +bool IsFullRootPath(const wchar *Path) +{ + return IsFullPath(Path) || IsPathDiv(Path[0]); +} + + bool IsDiskLetter(const wchar *Path) { wchar Letter=etoupperw(Path[0]); diff --git a/src/thirdparty/unrar/pathfn.hpp b/src/thirdparty/unrar/pathfn.hpp index fabb29340..ae1f8c2e8 100644 --- a/src/thirdparty/unrar/pathfn.hpp +++ b/src/thirdparty/unrar/pathfn.hpp @@ -56,6 +56,7 @@ inline void SlashToNative(const wchar *SrcName,wchar *DestName,size_t MaxLength) void ConvertNameToFull(const wchar *Src,wchar *Dest,size_t MaxSize); bool IsFullPath(const wchar *Path); +bool IsFullRootPath(const wchar *Path); bool IsDiskLetter(const wchar *Path); void GetPathRoot(const wchar *Path,wchar *Root,size_t MaxSize); int ParseVersionFileName(wchar *Name,bool Truncate); diff --git a/src/thirdparty/unrar/ulinks.cpp b/src/thirdparty/unrar/ulinks.cpp index b51ff6282..f3e51b52e 100644 --- a/src/thirdparty/unrar/ulinks.cpp +++ b/src/thirdparty/unrar/ulinks.cpp @@ -30,7 +30,13 @@ static bool UnixSymlink(const char *Target,const wchar *LinkName,RarTime *ftm,Ra } -bool ExtractUnixLink30(ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName) +static bool IsFullPath(const char *PathA) // Unix ASCII version. +{ + return *PathA==CPATHDIVIDER; +} + + +bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName) { char Target[NM]; if (IsLink(Arc.FileHead.FileAttr)) @@ -48,13 +54,16 @@ bool ExtractUnixLink30(ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName) if (!DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL)) return true; + if (!Cmd->AbsoluteLinks && (IsFullPath(Target) || + !IsRelativeSymlinkSafe(Arc.FileHead.FileName,Arc.FileHead.RedirName))) + return UnixSymlink(Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime); } return false; } -bool ExtractUnixLink50(const wchar *Name,FileHeader *hd) +bool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader *hd) { char Target[NM]; WideToChar(hd->RedirName,Target,ASIZE(Target)); @@ -68,5 +77,8 @@ bool ExtractUnixLink50(const wchar *Name,FileHeader *hd) return false; DosSlashToUnix(Target,Target,ASIZE(Target)); } + if (!Cmd->AbsoluteLinks && (IsFullPath(Target) || + !IsRelativeSymlinkSafe(hd->FileName,hd->RedirName))) + return false; return UnixSymlink(Target,Name,&hd->mtime,&hd->atime); } diff --git a/src/thirdparty/unrar/version.hpp b/src/thirdparty/unrar/version.hpp index b2844b691..8518b5516 100644 --- a/src/thirdparty/unrar/version.hpp +++ b/src/thirdparty/unrar/version.hpp @@ -1,6 +1,6 @@ #define RARVER_MAJOR 5 #define RARVER_MINOR 21 -#define RARVER_BETA 1 -#define RARVER_DAY 9 -#define RARVER_MONTH 1 +#define RARVER_BETA 0 +#define RARVER_DAY 15 +#define RARVER_MONTH 2 #define RARVER_YEAR 2015 diff --git a/src/thirdparty/unrar/win32lnk.cpp b/src/thirdparty/unrar/win32lnk.cpp index f911be98e..b291056f0 100644 --- a/src/thirdparty/unrar/win32lnk.cpp +++ b/src/thirdparty/unrar/win32lnk.cpp @@ -40,23 +40,6 @@ bool CreateReparsePoint(CommandData *Cmd,const wchar *Name,FileHeader *hd) PrivSet=true; } - CreatePath(Name,true); - - // 'DirTarget' check is important for Unix symlinks to directories. - // Unix symlinks do not have their own 'directory' attribute. - if (hd->Dir || hd->DirTarget) - { - if (!CreateDirectory(Name,NULL)) - return false; - } - else - { - HANDLE hFile=CreateFile(Name,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL); - if (hFile == INVALID_HANDLE_VALUE) - return false; - CloseHandle(hFile); - } - const DWORD BufSize=sizeof(REPARSE_DATA_BUFFER)+2*NM+1024; Array<byte> Buf(BufSize); REPARSE_DATA_BUFFER *rdb=(REPARSE_DATA_BUFFER *)&Buf[0]; @@ -79,6 +62,26 @@ bool CreateReparsePoint(CommandData *Cmd,const wchar *Name,FileHeader *hd) size_t PrintLength=wcslen(PrintName); bool AbsPath=WinPrefix; + if (!Cmd->AbsoluteLinks && (AbsPath || !IsRelativeSymlinkSafe(hd->FileName,hd->RedirName))) + return false; + + CreatePath(Name,true); + + // 'DirTarget' check is important for Unix symlinks to directories. + // Unix symlinks do not have their own 'directory' attribute. + if (hd->Dir || hd->DirTarget) + { + if (!CreateDirectory(Name,NULL)) + return false; + } + else + { + HANDLE hFile=CreateFile(Name,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL); + if (hFile == INVALID_HANDLE_VALUE) + return false; + CloseHandle(hFile); + } + if (hd->RedirType==FSREDIR_JUNCTION) { |