diff options
author | Underground78 <underground78@users.sourceforge.net> | 2015-01-25 15:47:48 +0300 |
---|---|---|
committer | Underground78 <underground78@users.sourceforge.net> | 2015-01-25 15:47:48 +0300 |
commit | 6fcba1bead7608fb480ab943ab9689bc66f4e009 (patch) | |
tree | ef5a968e7749e8f80f310fd44a43fc5b1d394193 /src/thirdparty/unrar/file.cpp | |
parent | 46ce9d630e7891230c9648afb0c17088681573e6 (diff) | |
parent | 013ebae50427b2e985939439202e206373ed5aee (diff) |
Merge branch 'release-1.7.8'1.7.8
Diffstat (limited to 'src/thirdparty/unrar/file.cpp')
-rw-r--r-- | src/thirdparty/unrar/file.cpp | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/src/thirdparty/unrar/file.cpp b/src/thirdparty/unrar/file.cpp index 51100acd6..8fba34adb 100644 --- a/src/thirdparty/unrar/file.cpp +++ b/src/thirdparty/unrar/file.cpp @@ -2,7 +2,7 @@ File::File() { - hFile=BAD_HANDLE; + hFile=FILE_BAD_HANDLE; *FileName=0; NewFile=false; LastWrite=false; @@ -22,7 +22,7 @@ File::File() File::~File() { - if (hFile!=BAD_HANDLE && !SkipClose) + if (hFile!=FILE_BAD_HANDLE && !SkipClose) if (NewFile) Delete(); else @@ -52,14 +52,14 @@ bool File::Open(const wchar *Name,uint Mode) uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ; if (UpdateMode) Access|=GENERIC_WRITE; - uint ShareMode=FILE_SHARE_READ; + uint ShareMode=(Mode & FMF_OPENEXCLUSIVE) ? 0 : FILE_SHARE_READ; if (OpenShared) ShareMode|=FILE_SHARE_WRITE; uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN; hNewFile=CreateFile(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL); DWORD LastError; - if (hNewFile==BAD_HANDLE) + if (hNewFile==FILE_BAD_HANDLE) { LastError=GetLastError(); @@ -85,7 +85,7 @@ bool File::Open(const wchar *Name,uint Mode) } } - if (hNewFile==BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND) + if (hNewFile==FILE_BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND) ErrorType=FILE_NOTFOUND; #else int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY); @@ -112,7 +112,7 @@ bool File::Open(const wchar *Name,uint Mode) } #endif if (handle==-1) - hNewFile=BAD_HANDLE; + hNewFile=FILE_BAD_HANDLE; else { #ifdef FILE_USE_OPEN @@ -121,13 +121,13 @@ bool File::Open(const wchar *Name,uint Mode) hNewFile=fdopen(handle,UpdateMode ? UPDATEBINARY:READBINARY); #endif } - if (hNewFile==BAD_HANDLE && errno==ENOENT) + if (hNewFile==FILE_BAD_HANDLE && errno==ENOENT) ErrorType=FILE_NOTFOUND; #endif NewFile=false; HandleType=FILE_HANDLENORMAL; SkipClose=false; - bool Success=hNewFile!=BAD_HANDLE; + bool Success=hNewFile!=FILE_BAD_HANDLE; if (Success) { hFile=hNewFile; @@ -167,9 +167,18 @@ bool File::Create(const wchar *Name,uint Mode) CreateMode=Mode; uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ|GENERIC_WRITE; DWORD ShareMode=ShareRead ? FILE_SHARE_READ:0; - hFile=CreateFile(Name,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL); - if (hFile==BAD_HANDLE) + // Windows automatically removes dots and spaces in the end of file name, + // So we detect such names and process them with \\?\ prefix. + wchar *LastChar=PointToLastChar(Name); + bool Special=*LastChar=='.' || *LastChar==' '; + + if (Special) + hFile=FILE_BAD_HANDLE; + else + hFile=CreateFile(Name,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL); + + if (hFile==FILE_BAD_HANDLE) { wchar LongName[NM]; if (GetWinLongPath(Name,LongName,ASIZE(LongName))) @@ -181,6 +190,10 @@ bool File::Create(const wchar *Name,uint Mode) WideToChar(Name,NameA,ASIZE(NameA)); #ifdef FILE_USE_OPEN hFile=open(NameA,(O_CREAT|O_TRUNC) | (WriteMode ? O_WRONLY : O_RDWR)); +#ifdef _ANDROID + if (hFile==FILE_BAD_HANDLE) + hFile=JniCreateFile(Name); // If external card is read-only for usual file API. +#endif #else hFile=fopen(NameA,WriteMode ? WRITEBINARY:CREATEBINARY); #endif @@ -189,7 +202,7 @@ bool File::Create(const wchar *Name,uint Mode) HandleType=FILE_HANDLENORMAL; SkipClose=false; wcsncpyz(FileName,Name,ASIZE(FileName)); - return hFile!=BAD_HANDLE; + return hFile!=FILE_BAD_HANDLE; } @@ -215,7 +228,7 @@ bool File::Close() { bool Success=true; - if (hFile!=BAD_HANDLE) + if (hFile!=FILE_BAD_HANDLE) { if (!SkipClose) { @@ -232,7 +245,7 @@ bool File::Close() #endif #endif } - hFile=BAD_HANDLE; + hFile=FILE_BAD_HANDLE; } HandleType=FILE_HANDLENORMAL; if (!Success && AllowExceptions) @@ -245,7 +258,7 @@ bool File::Delete() { if (HandleType!=FILE_HANDLENORMAL) return false; - if (hFile!=BAD_HANDLE) + if (hFile!=FILE_BAD_HANDLE) Close(); if (!AllowDelete) return false; @@ -278,7 +291,7 @@ void File::Write(const void *Data,size_t Size) hFile=GetStdHandle(STD_OUTPUT_HANDLE); #else // Cannot use the standard stdout here, because it already has wide orientation. - if (hFile==BAD_HANDLE) + if (hFile==FILE_BAD_HANDLE) { #ifdef FILE_USE_OPEN hFile=dup(STDOUT_FILENO); // Open new stdout stream. @@ -390,8 +403,8 @@ int File::DirectRead(void *Data,size_t Size) if (HandleType==FILE_HANDLESTD) { #ifdef _WIN_ALL - if (Size>MaxDeviceRead) - Size=MaxDeviceRead; +// if (Size>MaxDeviceRead) +// Size=MaxDeviceRead; hFile=GetStdHandle(STD_INPUT_HANDLE); #else #ifdef FILE_USE_OPEN @@ -402,6 +415,8 @@ int File::DirectRead(void *Data,size_t Size) #endif } #ifdef _WIN_ALL + // For pipes like 'type file.txt | rar -si arcname' ReadFile may return + // data in small ~4KB blocks. It may slightly reduce the compression ratio. DWORD Read; if (!ReadFile(hFile,Data,(DWORD)Size,&Read,NULL)) { @@ -454,7 +469,7 @@ void File::Seek(int64 Offset,int Method) bool File::RawSeek(int64 Offset,int Method) { - if (hFile==BAD_HANDLE) + if (hFile==FILE_BAD_HANDLE) return true; if (Offset<0 && Method!=SEEK_SET) { @@ -485,7 +500,7 @@ bool File::RawSeek(int64 Offset,int Method) int64 File::Tell() { - if (hFile==BAD_HANDLE) + if (hFile==FILE_BAD_HANDLE) if (AllowExceptions) ErrHandler.SeekError(FileName); else @@ -636,7 +651,7 @@ int64 File::FileLength() bool File::IsDevice() { - if (hFile==BAD_HANDLE) + if (hFile==FILE_BAD_HANDLE) return false; #ifdef _WIN_ALL uint Type=GetFileType(hFile); @@ -650,7 +665,7 @@ bool File::IsDevice() #ifndef SFX_MODULE int64 File::Copy(File &Dest,int64 Length) { - Array<char> Buffer(0x10000); + Array<char> Buffer(0x40000); int64 CopySize=0; bool CopyAll=(Length==INT64NDF); @@ -667,7 +682,7 @@ int64 File::Copy(File &Dest,int64 Length) // For FAT32 USB flash drives in Windows if first write is 4 KB or more, // write caching is disabled and "write through" is enabled, resulting // in bad performance, especially for many small files. It happens when - // we create SFX archive on USB drive, because SFX module is writetn first. + // we create SFX archive on USB drive, because SFX module is written first. // So we split the first write to small 1 KB followed by rest of data. if (CopySize==0 && WriteSize>=4096) { |