diff options
Diffstat (limited to '3rdparty/lzma/CPP/Windows/FileIO.h')
-rw-r--r-- | 3rdparty/lzma/CPP/Windows/FileIO.h | 227 |
1 files changed, 207 insertions, 20 deletions
diff --git a/3rdparty/lzma/CPP/Windows/FileIO.h b/3rdparty/lzma/CPP/Windows/FileIO.h index 32c285fb9cc..03e061a980b 100644 --- a/3rdparty/lzma/CPP/Windows/FileIO.h +++ b/3rdparty/lzma/CPP/Windows/FileIO.h @@ -1,32 +1,50 @@ // Windows/FileIO.h -#ifndef __WINDOWS_FILE_IO_H -#define __WINDOWS_FILE_IO_H +#ifndef ZIP7_INC_WINDOWS_FILE_IO_H +#define ZIP7_INC_WINDOWS_FILE_IO_H #include "../Common/MyWindows.h" +#define Z7_WIN_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) +#define Z7_WIN_IO_REPARSE_TAG_SYMLINK (0xA000000CL) +#define Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK (0xA000001DL) + +#define Z7_WIN_SYMLINK_FLAG_RELATIVE 1 + +// what the meaning of that FLAG or field (2)? +#define Z7_WIN_LX_SYMLINK_FLAG 2 + +#ifdef _WIN32 + #if defined(_WIN32) && !defined(UNDER_CE) #include <winioctl.h> #endif +#else + +#include <sys/types.h> +#include <sys/stat.h> + +#endif + #include "../Common/MyString.h" #include "../Common/MyBuffer.h" -#include "Defs.h" +#include "../Windows/TimeUtils.h" -#define _my_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) -#define _my_IO_REPARSE_TAG_SYMLINK (0xA000000CL) +#include "Defs.h" -#define _my_SYMLINK_FLAG_RELATIVE 1 +HRESULT GetLastError_noZero_HRESULT(); -#define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER -#define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER +#define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER +#define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER +#define my_FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER namespace NWindows { namespace NFile { #if defined(_WIN32) && !defined(UNDER_CE) -bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink); +bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink, bool isWSL); #endif struct CReparseShortInfo @@ -44,24 +62,56 @@ struct CReparseAttr UString SubsName; UString PrintName; + AString WslName; + + bool HeaderError; + bool TagIsUnknown; + bool MinorError; + DWORD ErrorCode; + CReparseAttr(): Tag(0), Flags(0) {} + + // Parse() + // returns (true) and (ErrorCode = 0), if (it'a correct known link) + // returns (false) and (ErrorCode = ERROR_REPARSE_TAG_INVALID), if unknown tag bool Parse(const Byte *p, size_t size); - bool IsMountPoint() const { return Tag == _my_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction - bool IsSymLink() const { return Tag == _my_IO_REPARSE_TAG_SYMLINK; } - bool IsRelative() const { return Flags == _my_SYMLINK_FLAG_RELATIVE; } + bool IsMountPoint() const { return Tag == Z7_WIN_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction + bool IsSymLink_Win() const { return Tag == Z7_WIN_IO_REPARSE_TAG_SYMLINK; } + bool IsSymLink_WSL() const { return Tag == Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK; } + + bool IsRelative_Win() const { return Flags == Z7_WIN_SYMLINK_FLAG_RELATIVE; } + + bool IsRelative_WSL() const + { + if (WslName.IsEmpty()) + return true; + char c = WslName[0]; + return !IS_PATH_SEPAR(c); + } + // bool IsVolume() const; bool IsOkNamePair() const; UString GetPath() const; }; +#ifdef _WIN32 +#define CFiInfo BY_HANDLE_FILE_INFORMATION +#define ST_MTIME(st) (st).ftLastWriteTime +#else +#define CFiInfo stat +#endif + +#ifdef _WIN32 + namespace NIO { bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo = NULL); bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size); +bool DeleteReparseData(CFSTR path); -class CFileBase +class CFileBase MY_UNCOPYABLE { protected: HANDLE _handle; @@ -90,15 +140,20 @@ public: } public: - #ifdef SUPPORT_DEVICE_FILE + bool PreserveATime; + #ifdef Z7_DEVICE_FILE bool IsDeviceFile; bool SizeDefined; UInt64 Size; // it can be larger than real available size #endif - CFileBase(): _handle(INVALID_HANDLE_VALUE) {}; + CFileBase(): _handle(INVALID_HANDLE_VALUE), PreserveATime(false) {} ~CFileBase() { Close(); } + HANDLE GetHandle() const { return _handle; } + + // void Detach() { _handle = INVALID_HANDLE_VALUE; } + bool Close() throw(); bool GetPosition(UInt64 &position) const throw(); @@ -114,6 +169,7 @@ public: static bool GetFileInformation(CFSTR path, BY_HANDLE_FILE_INFORMATION *info) { + // probably it can work for complex paths: unsupported by another things NIO::CFileBase file; if (!file.Create(path, 0, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS)) return false; @@ -139,7 +195,7 @@ struct my_DISK_GEOMETRY_EX class CInFile: public CFileBase { - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE #ifndef UNDER_CE @@ -169,9 +225,31 @@ public: #ifndef UNDER_CE + bool Open_for_ReadAttributes(CFSTR fileName) + { + return Create(fileName, FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS); + // we must use (FILE_FLAG_BACKUP_SEMANTICS) to open handle of directory. + } + + bool Open_for_FileRenameInformation(CFSTR fileName) + { + return Create(fileName, DELETE | SYNCHRONIZE | GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); + // we must use (FILE_FLAG_BACKUP_SEMANTICS) to open handle of directory. + } + bool OpenReparse(CFSTR fileName) { - return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, + // 17.02 fix: to support Windows XP compatibility junctions: + // we use Create() with (desiredAccess = 0) instead of Open() with GENERIC_READ + return + Create(fileName, 0, + // Open(fileName, + FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS); } @@ -180,6 +258,7 @@ public: bool Read1(void *data, UInt32 size, UInt32 &processedSize) throw(); bool ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw(); bool Read(void *data, UInt32 size, UInt32 &processedSize) throw(); + bool ReadFull(void *data, size_t size, size_t &processedSize) throw(); }; class COutFile: public CFileBase @@ -190,14 +269,122 @@ public: bool Create(CFSTR fileName, bool createAlways); bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes); - bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw(); - bool SetMTime(const FILETIME *mTime) throw(); + bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw(); + bool SetMTime(const CFiTime *mTime) throw(); bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw(); bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw(); + bool WriteFull(const void *data, size_t size) throw(); bool SetEndOfFile() throw(); bool SetLength(UInt64 length) throw(); + bool SetLength_KeepPosition(UInt64 length) throw(); +}; + +} + + +#else // _WIN32 + +namespace NIO { + +bool GetReparseData(CFSTR path, CByteBuffer &reparseData); +// bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size); + +// parameters are in reverse order of symlink() function !!! +bool SetSymLink(CFSTR from, CFSTR to); +bool SetSymLink_UString(CFSTR from, const UString &to); + + +class CFileBase +{ +protected: + int _handle; + + /* + bool IsDeviceFile; + bool SizeDefined; + UInt64 Size; // it can be larger than real available size + */ + + bool OpenBinary(const char *name, int flags, mode_t mode = 0666); +public: + bool PreserveATime; + + CFileBase(): _handle(-1), PreserveATime(false) {} + ~CFileBase() { Close(); } + // void Detach() { _handle = -1; } + bool Close(); + bool GetLength(UInt64 &length) const; + off_t seek(off_t distanceToMove, int moveMethod) const; + off_t seekToBegin() const throw(); + off_t seekToCur() const throw(); + // bool SeekToBegin() throw(); + int my_fstat(struct stat *st) const { return fstat(_handle, st); } + /* + int my_ioctl_BLKGETSIZE64(unsigned long long *val); + int GetDeviceSize_InBytes(UInt64 &size); + void CalcDeviceSize(CFSTR s); + */ +}; + +class CInFile: public CFileBase +{ +public: + bool Open(const char *name); + bool OpenShared(const char *name, bool shareForWrite); + ssize_t read_part(void *data, size_t size) throw(); + // ssize_t read_full(void *data, size_t size, size_t &processed); + bool ReadFull(void *data, size_t size, size_t &processedSize) throw(); +}; + +class COutFile: public CFileBase +{ + bool CTime_defined; + bool ATime_defined; + bool MTime_defined; + CFiTime CTime; + CFiTime ATime; + CFiTime MTime; + + AString Path; + ssize_t write_part(const void *data, size_t size) throw(); +public: + mode_t mode_for_Create; + + COutFile(): + CTime_defined(false), + ATime_defined(false), + MTime_defined(false), + mode_for_Create(0666) + {} + + bool Close(); + bool Create(const char *name, bool createAlways); + bool Open(const char *name, DWORD creationDisposition); + ssize_t write_full(const void *data, size_t size, size_t &processed) throw(); + + bool WriteFull(const void *data, size_t size) throw() + { + size_t processed; + ssize_t res = write_full(data, size, processed); + if (res == -1) + return false; + return processed == size; + } + + bool SetLength(UInt64 length) throw(); + bool SetLength_KeepPosition(UInt64 length) throw() + { + return SetLength(length); + } + bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw(); + bool SetMTime(const CFiTime *mTime) throw(); }; -}}} +} + +#endif // _WIN32 + +}} + #endif |