1 // Windows/FileIO.h 2 3 #ifndef __WINDOWS_FILE_IO_H 4 #define __WINDOWS_FILE_IO_H 5 6 #include "../Common/MyWindows.h" 7 8 #if defined(_WIN32) && !defined(UNDER_CE) 9 #include <winioctl.h> 10 #endif 11 12 #include "../Common/MyString.h" 13 #include "../Common/MyBuffer.h" 14 15 #include "Defs.h" 16 17 #define _my_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) 18 #define _my_IO_REPARSE_TAG_SYMLINK (0xA000000CL) 19 20 #define _my_SYMLINK_FLAG_RELATIVE 1 21 22 #define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER 23 #define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER 24 25 namespace NWindows { 26 namespace NFile { 27 28 #if defined(_WIN32) && !defined(UNDER_CE) 29 bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink); 30 #endif 31 32 struct CReparseShortInfo 33 { 34 unsigned Offset; 35 unsigned Size; 36 37 bool Parse(const Byte *p, size_t size); 38 }; 39 40 struct CReparseAttr 41 { 42 UInt32 Tag; 43 UInt32 Flags; 44 UString SubsName; 45 UString PrintName; 46 CReparseAttrCReparseAttr47 CReparseAttr(): Tag(0), Flags(0) {} 48 bool Parse(const Byte *p, size_t size); 49 IsMountPointCReparseAttr50 bool IsMountPoint() const { return Tag == _my_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction IsSymLinkCReparseAttr51 bool IsSymLink() const { return Tag == _my_IO_REPARSE_TAG_SYMLINK; } IsRelativeCReparseAttr52 bool IsRelative() const { return Flags == _my_SYMLINK_FLAG_RELATIVE; } 53 // bool IsVolume() const; 54 55 bool IsOkNamePair() const; 56 UString GetPath() const; 57 }; 58 59 namespace NIO { 60 61 bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo = NULL); 62 bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size); 63 64 class CFileBase 65 { 66 protected: 67 HANDLE _handle; 68 69 bool Create(CFSTR path, DWORD desiredAccess, 70 DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); 71 72 public: 73 74 bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize, 75 LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped = NULL) const 76 { 77 return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize, 78 outBuffer, outSize, bytesReturned, overlapped)); 79 } 80 DeviceIoControlOut(DWORD controlCode,LPVOID outBuffer,DWORD outSize,LPDWORD bytesReturned)81 bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned) const 82 { 83 return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize, bytesReturned); 84 } 85 DeviceIoControlOut(DWORD controlCode,LPVOID outBuffer,DWORD outSize)86 bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const 87 { 88 DWORD bytesReturned; 89 return DeviceIoControlOut(controlCode, outBuffer, outSize, &bytesReturned); 90 } 91 92 public: 93 #ifdef SUPPORT_DEVICE_FILE 94 bool IsDeviceFile; 95 bool SizeDefined; 96 UInt64 Size; // it can be larger than real available size 97 #endif 98 CFileBase()99 CFileBase(): _handle(INVALID_HANDLE_VALUE) {}; ~CFileBase()100 ~CFileBase() { Close(); } 101 102 bool Close() throw(); 103 104 bool GetPosition(UInt64 &position) const throw(); 105 bool GetLength(UInt64 &length) const throw(); 106 107 bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw(); 108 bool Seek(UInt64 position, UInt64 &newPosition) const throw(); 109 bool SeekToBegin() const throw(); 110 bool SeekToEnd(UInt64 &newPosition) const throw(); 111 GetFileInformation(BY_HANDLE_FILE_INFORMATION * info)112 bool GetFileInformation(BY_HANDLE_FILE_INFORMATION *info) const 113 { return BOOLToBool(GetFileInformationByHandle(_handle, info)); } 114 GetFileInformation(CFSTR path,BY_HANDLE_FILE_INFORMATION * info)115 static bool GetFileInformation(CFSTR path, BY_HANDLE_FILE_INFORMATION *info) 116 { 117 NIO::CFileBase file; 118 if (!file.Create(path, 0, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS)) 119 return false; 120 return file.GetFileInformation(info); 121 } 122 }; 123 124 #ifndef UNDER_CE 125 #define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM 126 #define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) 127 // #define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) 128 129 // IOCTL_DISK_GET_DRIVE_GEOMETRY_EX works since WinXP 130 #define my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS) 131 132 struct my_DISK_GEOMETRY_EX 133 { 134 DISK_GEOMETRY Geometry; 135 LARGE_INTEGER DiskSize; 136 BYTE Data[1]; 137 }; 138 #endif 139 140 class CInFile: public CFileBase 141 { 142 #ifdef SUPPORT_DEVICE_FILE 143 144 #ifndef UNDER_CE 145 GetGeometry(DISK_GEOMETRY * res)146 bool GetGeometry(DISK_GEOMETRY *res) const 147 { return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); } 148 GetGeometryEx(my_DISK_GEOMETRY_EX * res)149 bool GetGeometryEx(my_DISK_GEOMETRY_EX *res) const 150 { return DeviceIoControlOut(my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, res, sizeof(*res)); } 151 GetCdRomGeometry(DISK_GEOMETRY * res)152 bool GetCdRomGeometry(DISK_GEOMETRY *res) const 153 { return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); } 154 GetPartitionInfo(PARTITION_INFORMATION * res)155 bool GetPartitionInfo(PARTITION_INFORMATION *res) 156 { return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); } 157 158 #endif 159 160 void CorrectDeviceSize(); 161 void CalcDeviceSize(CFSTR name); 162 163 #endif 164 165 public: 166 bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); 167 bool OpenShared(CFSTR fileName, bool shareForWrite); 168 bool Open(CFSTR fileName); 169 170 #ifndef UNDER_CE 171 OpenReparse(CFSTR fileName)172 bool OpenReparse(CFSTR fileName) 173 { 174 return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, 175 FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS); 176 } 177 178 #endif 179 180 bool Read1(void *data, UInt32 size, UInt32 &processedSize) throw(); 181 bool ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw(); 182 bool Read(void *data, UInt32 size, UInt32 &processedSize) throw(); 183 }; 184 185 class COutFile: public CFileBase 186 { 187 public: 188 bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); 189 bool Open(CFSTR fileName, DWORD creationDisposition); 190 bool Create(CFSTR fileName, bool createAlways); 191 bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes); 192 193 bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw(); 194 bool SetMTime(const FILETIME *mTime) throw(); 195 bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw(); 196 bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw(); 197 bool SetEndOfFile() throw(); 198 bool SetLength(UInt64 length) throw(); 199 }; 200 201 }}} 202 203 #endif 204