1370b324cSopenharmony_ci// FileStreams.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci// #include <stdio.h> 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#ifndef _WIN32 8370b324cSopenharmony_ci#include <fcntl.h> 9370b324cSopenharmony_ci#include <unistd.h> 10370b324cSopenharmony_ci#include <errno.h> 11370b324cSopenharmony_ci#include <grp.h> 12370b324cSopenharmony_ci#include <pwd.h> 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci// for major()/minor(): 15370b324cSopenharmony_ci#include <sys/types.h> 16370b324cSopenharmony_ci#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) 17370b324cSopenharmony_ci#else 18370b324cSopenharmony_ci#ifndef major 19370b324cSopenharmony_ci#include <sys/sysmacros.h> 20370b324cSopenharmony_ci#endif 21370b324cSopenharmony_ci#endif 22370b324cSopenharmony_ci 23370b324cSopenharmony_ci#endif // _WIN32 24370b324cSopenharmony_ci 25370b324cSopenharmony_ci#include "../../Windows/FileFind.h" 26370b324cSopenharmony_ci 27370b324cSopenharmony_ci#ifdef Z7_DEVICE_FILE 28370b324cSopenharmony_ci#include "../../../C/Alloc.h" 29370b324cSopenharmony_ci#include "../../Common/Defs.h" 30370b324cSopenharmony_ci#endif 31370b324cSopenharmony_ci 32370b324cSopenharmony_ci#include "../PropID.h" 33370b324cSopenharmony_ci 34370b324cSopenharmony_ci#include "FileStreams.h" 35370b324cSopenharmony_ci 36370b324cSopenharmony_cistatic inline HRESULT GetLastError_HRESULT() 37370b324cSopenharmony_ci{ 38370b324cSopenharmony_ci DWORD lastError = ::GetLastError(); 39370b324cSopenharmony_ci if (lastError == 0) 40370b324cSopenharmony_ci return E_FAIL; 41370b324cSopenharmony_ci return HRESULT_FROM_WIN32(lastError); 42370b324cSopenharmony_ci} 43370b324cSopenharmony_ci 44370b324cSopenharmony_cistatic inline HRESULT ConvertBoolToHRESULT(bool result) 45370b324cSopenharmony_ci{ 46370b324cSopenharmony_ci if (result) 47370b324cSopenharmony_ci return S_OK; 48370b324cSopenharmony_ci return GetLastError_HRESULT(); 49370b324cSopenharmony_ci} 50370b324cSopenharmony_ci 51370b324cSopenharmony_ci 52370b324cSopenharmony_ci#ifdef Z7_DEVICE_FILE 53370b324cSopenharmony_cistatic const UInt32 kClusterSize = 1 << 18; 54370b324cSopenharmony_ci#endif 55370b324cSopenharmony_ci 56370b324cSopenharmony_ciCInFileStream::CInFileStream(): 57370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 58370b324cSopenharmony_ci VirtPos(0), 59370b324cSopenharmony_ci PhyPos(0), 60370b324cSopenharmony_ci Buf(NULL), 61370b324cSopenharmony_ci BufSize(0), 62370b324cSopenharmony_ci #endif 63370b324cSopenharmony_ci #ifndef _WIN32 64370b324cSopenharmony_ci _uid(0), 65370b324cSopenharmony_ci _gid(0), 66370b324cSopenharmony_ci StoreOwnerId(false), 67370b324cSopenharmony_ci StoreOwnerName(false), 68370b324cSopenharmony_ci #endif 69370b324cSopenharmony_ci _info_WasLoaded(false), 70370b324cSopenharmony_ci SupportHardLinks(false), 71370b324cSopenharmony_ci Callback(NULL), 72370b324cSopenharmony_ci CallbackRef(0) 73370b324cSopenharmony_ci{ 74370b324cSopenharmony_ci} 75370b324cSopenharmony_ci 76370b324cSopenharmony_ciCInFileStream::~CInFileStream() 77370b324cSopenharmony_ci{ 78370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 79370b324cSopenharmony_ci MidFree(Buf); 80370b324cSopenharmony_ci #endif 81370b324cSopenharmony_ci 82370b324cSopenharmony_ci if (Callback) 83370b324cSopenharmony_ci Callback->InFileStream_On_Destroy(this, CallbackRef); 84370b324cSopenharmony_ci} 85370b324cSopenharmony_ci 86370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) 87370b324cSopenharmony_ci{ 88370b324cSopenharmony_ci #ifdef Z7_FILE_STREAMS_USE_WIN_FILE 89370b324cSopenharmony_ci 90370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 91370b324cSopenharmony_ci if (processedSize) 92370b324cSopenharmony_ci *processedSize = 0; 93370b324cSopenharmony_ci if (size == 0) 94370b324cSopenharmony_ci return S_OK; 95370b324cSopenharmony_ci if (File.IsDeviceFile) 96370b324cSopenharmony_ci { 97370b324cSopenharmony_ci if (File.SizeDefined) 98370b324cSopenharmony_ci { 99370b324cSopenharmony_ci if (VirtPos >= File.Size) 100370b324cSopenharmony_ci return VirtPos == File.Size ? S_OK : E_FAIL; 101370b324cSopenharmony_ci const UInt64 rem = File.Size - VirtPos; 102370b324cSopenharmony_ci if (size > rem) 103370b324cSopenharmony_ci size = (UInt32)rem; 104370b324cSopenharmony_ci } 105370b324cSopenharmony_ci for (;;) 106370b324cSopenharmony_ci { 107370b324cSopenharmony_ci const UInt32 mask = kClusterSize - 1; 108370b324cSopenharmony_ci const UInt64 mask2 = ~(UInt64)mask; 109370b324cSopenharmony_ci const UInt64 alignedPos = VirtPos & mask2; 110370b324cSopenharmony_ci if (BufSize > 0 && BufStartPos == alignedPos) 111370b324cSopenharmony_ci { 112370b324cSopenharmony_ci const UInt32 pos = (UInt32)VirtPos & mask; 113370b324cSopenharmony_ci if (pos >= BufSize) 114370b324cSopenharmony_ci return S_OK; 115370b324cSopenharmony_ci const UInt32 rem = MyMin(BufSize - pos, size); 116370b324cSopenharmony_ci memcpy(data, Buf + pos, rem); 117370b324cSopenharmony_ci VirtPos += rem; 118370b324cSopenharmony_ci if (processedSize) 119370b324cSopenharmony_ci *processedSize += rem; 120370b324cSopenharmony_ci return S_OK; 121370b324cSopenharmony_ci } 122370b324cSopenharmony_ci 123370b324cSopenharmony_ci bool useBuf = false; 124370b324cSopenharmony_ci if ((VirtPos & mask) != 0 || ((size_t)(ptrdiff_t)data & mask) != 0 ) 125370b324cSopenharmony_ci useBuf = true; 126370b324cSopenharmony_ci else 127370b324cSopenharmony_ci { 128370b324cSopenharmony_ci UInt64 end = VirtPos + size; 129370b324cSopenharmony_ci if ((end & mask) != 0) 130370b324cSopenharmony_ci { 131370b324cSopenharmony_ci end &= mask2; 132370b324cSopenharmony_ci if (end <= VirtPos) 133370b324cSopenharmony_ci useBuf = true; 134370b324cSopenharmony_ci else 135370b324cSopenharmony_ci size = (UInt32)(end - VirtPos); 136370b324cSopenharmony_ci } 137370b324cSopenharmony_ci } 138370b324cSopenharmony_ci if (!useBuf) 139370b324cSopenharmony_ci break; 140370b324cSopenharmony_ci if (alignedPos != PhyPos) 141370b324cSopenharmony_ci { 142370b324cSopenharmony_ci UInt64 realNewPosition; 143370b324cSopenharmony_ci const bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition); 144370b324cSopenharmony_ci if (!result) 145370b324cSopenharmony_ci return ConvertBoolToHRESULT(result); 146370b324cSopenharmony_ci PhyPos = realNewPosition; 147370b324cSopenharmony_ci } 148370b324cSopenharmony_ci 149370b324cSopenharmony_ci BufStartPos = alignedPos; 150370b324cSopenharmony_ci UInt32 readSize = kClusterSize; 151370b324cSopenharmony_ci if (File.SizeDefined) 152370b324cSopenharmony_ci readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize); 153370b324cSopenharmony_ci 154370b324cSopenharmony_ci if (!Buf) 155370b324cSopenharmony_ci { 156370b324cSopenharmony_ci Buf = (Byte *)MidAlloc(kClusterSize); 157370b324cSopenharmony_ci if (!Buf) 158370b324cSopenharmony_ci return E_OUTOFMEMORY; 159370b324cSopenharmony_ci } 160370b324cSopenharmony_ci const bool result = File.Read1(Buf, readSize, BufSize); 161370b324cSopenharmony_ci if (!result) 162370b324cSopenharmony_ci return ConvertBoolToHRESULT(result); 163370b324cSopenharmony_ci 164370b324cSopenharmony_ci if (BufSize == 0) 165370b324cSopenharmony_ci return S_OK; 166370b324cSopenharmony_ci PhyPos += BufSize; 167370b324cSopenharmony_ci } 168370b324cSopenharmony_ci 169370b324cSopenharmony_ci if (VirtPos != PhyPos) 170370b324cSopenharmony_ci { 171370b324cSopenharmony_ci UInt64 realNewPosition; 172370b324cSopenharmony_ci bool result = File.Seek((Int64)VirtPos, FILE_BEGIN, realNewPosition); 173370b324cSopenharmony_ci if (!result) 174370b324cSopenharmony_ci return ConvertBoolToHRESULT(result); 175370b324cSopenharmony_ci PhyPos = VirtPos = realNewPosition; 176370b324cSopenharmony_ci } 177370b324cSopenharmony_ci } 178370b324cSopenharmony_ci #endif 179370b324cSopenharmony_ci 180370b324cSopenharmony_ci UInt32 realProcessedSize; 181370b324cSopenharmony_ci const bool result = File.ReadPart(data, size, realProcessedSize); 182370b324cSopenharmony_ci if (processedSize) 183370b324cSopenharmony_ci *processedSize = realProcessedSize; 184370b324cSopenharmony_ci 185370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 186370b324cSopenharmony_ci VirtPos += realProcessedSize; 187370b324cSopenharmony_ci PhyPos += realProcessedSize; 188370b324cSopenharmony_ci #endif 189370b324cSopenharmony_ci 190370b324cSopenharmony_ci if (result) 191370b324cSopenharmony_ci return S_OK; 192370b324cSopenharmony_ci 193370b324cSopenharmony_ci #else // Z7_FILE_STREAMS_USE_WIN_FILE 194370b324cSopenharmony_ci 195370b324cSopenharmony_ci if (processedSize) 196370b324cSopenharmony_ci *processedSize = 0; 197370b324cSopenharmony_ci const ssize_t res = File.read_part(data, (size_t)size); 198370b324cSopenharmony_ci if (res != -1) 199370b324cSopenharmony_ci { 200370b324cSopenharmony_ci if (processedSize) 201370b324cSopenharmony_ci *processedSize = (UInt32)res; 202370b324cSopenharmony_ci return S_OK; 203370b324cSopenharmony_ci } 204370b324cSopenharmony_ci #endif // Z7_FILE_STREAMS_USE_WIN_FILE 205370b324cSopenharmony_ci 206370b324cSopenharmony_ci { 207370b324cSopenharmony_ci const DWORD error = ::GetLastError(); 208370b324cSopenharmony_ci if (Callback) 209370b324cSopenharmony_ci return Callback->InFileStream_On_Error(CallbackRef, error); 210370b324cSopenharmony_ci if (error == 0) 211370b324cSopenharmony_ci return E_FAIL; 212370b324cSopenharmony_ci return HRESULT_FROM_WIN32(error); 213370b324cSopenharmony_ci } 214370b324cSopenharmony_ci} 215370b324cSopenharmony_ci 216370b324cSopenharmony_ci#ifdef UNDER_CE 217370b324cSopenharmony_ciZ7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) 218370b324cSopenharmony_ci{ 219370b324cSopenharmony_ci size_t s2 = fread(data, 1, size, stdin); 220370b324cSopenharmony_ci int error = ferror(stdin); 221370b324cSopenharmony_ci if (processedSize) 222370b324cSopenharmony_ci *processedSize = s2; 223370b324cSopenharmony_ci if (s2 <= size && error == 0) 224370b324cSopenharmony_ci return S_OK; 225370b324cSopenharmony_ci return E_FAIL; 226370b324cSopenharmony_ci} 227370b324cSopenharmony_ci#else 228370b324cSopenharmony_ciZ7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) 229370b324cSopenharmony_ci{ 230370b324cSopenharmony_ci #ifdef _WIN32 231370b324cSopenharmony_ci 232370b324cSopenharmony_ci DWORD realProcessedSize; 233370b324cSopenharmony_ci UInt32 sizeTemp = (1 << 20); 234370b324cSopenharmony_ci if (sizeTemp > size) 235370b324cSopenharmony_ci sizeTemp = size; 236370b324cSopenharmony_ci BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL); 237370b324cSopenharmony_ci if (processedSize) 238370b324cSopenharmony_ci *processedSize = realProcessedSize; 239370b324cSopenharmony_ci if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) 240370b324cSopenharmony_ci return S_OK; 241370b324cSopenharmony_ci return ConvertBoolToHRESULT(res != FALSE); 242370b324cSopenharmony_ci 243370b324cSopenharmony_ci #else 244370b324cSopenharmony_ci 245370b324cSopenharmony_ci if (processedSize) 246370b324cSopenharmony_ci *processedSize = 0; 247370b324cSopenharmony_ci ssize_t res; 248370b324cSopenharmony_ci do 249370b324cSopenharmony_ci { 250370b324cSopenharmony_ci res = read(0, data, (size_t)size); 251370b324cSopenharmony_ci } 252370b324cSopenharmony_ci while (res < 0 && (errno == EINTR)); 253370b324cSopenharmony_ci if (res == -1) 254370b324cSopenharmony_ci return GetLastError_HRESULT(); 255370b324cSopenharmony_ci if (processedSize) 256370b324cSopenharmony_ci *processedSize = (UInt32)res; 257370b324cSopenharmony_ci return S_OK; 258370b324cSopenharmony_ci 259370b324cSopenharmony_ci #endif 260370b324cSopenharmony_ci} 261370b324cSopenharmony_ci 262370b324cSopenharmony_ci#endif 263370b324cSopenharmony_ci 264370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) 265370b324cSopenharmony_ci{ 266370b324cSopenharmony_ci if (seekOrigin >= 3) 267370b324cSopenharmony_ci return STG_E_INVALIDFUNCTION; 268370b324cSopenharmony_ci 269370b324cSopenharmony_ci #ifdef Z7_FILE_STREAMS_USE_WIN_FILE 270370b324cSopenharmony_ci 271370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 272370b324cSopenharmony_ci if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END)) 273370b324cSopenharmony_ci { 274370b324cSopenharmony_ci switch (seekOrigin) 275370b324cSopenharmony_ci { 276370b324cSopenharmony_ci case STREAM_SEEK_SET: break; 277370b324cSopenharmony_ci case STREAM_SEEK_CUR: offset += VirtPos; break; 278370b324cSopenharmony_ci case STREAM_SEEK_END: offset += File.Size; break; 279370b324cSopenharmony_ci default: return STG_E_INVALIDFUNCTION; 280370b324cSopenharmony_ci } 281370b324cSopenharmony_ci if (offset < 0) 282370b324cSopenharmony_ci return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; 283370b324cSopenharmony_ci VirtPos = (UInt64)offset; 284370b324cSopenharmony_ci if (newPosition) 285370b324cSopenharmony_ci *newPosition = (UInt64)offset; 286370b324cSopenharmony_ci return S_OK; 287370b324cSopenharmony_ci } 288370b324cSopenharmony_ci #endif 289370b324cSopenharmony_ci 290370b324cSopenharmony_ci UInt64 realNewPosition = 0; 291370b324cSopenharmony_ci const bool result = File.Seek(offset, seekOrigin, realNewPosition); 292370b324cSopenharmony_ci const HRESULT hres = ConvertBoolToHRESULT(result); 293370b324cSopenharmony_ci 294370b324cSopenharmony_ci /* 21.07: new File.Seek() in 21.07 already returns correct (realNewPosition) 295370b324cSopenharmony_ci in case of error. So we don't need additional code below */ 296370b324cSopenharmony_ci // if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); } 297370b324cSopenharmony_ci 298370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 299370b324cSopenharmony_ci PhyPos = VirtPos = realNewPosition; 300370b324cSopenharmony_ci #endif 301370b324cSopenharmony_ci 302370b324cSopenharmony_ci if (newPosition) 303370b324cSopenharmony_ci *newPosition = realNewPosition; 304370b324cSopenharmony_ci 305370b324cSopenharmony_ci return hres; 306370b324cSopenharmony_ci 307370b324cSopenharmony_ci #else 308370b324cSopenharmony_ci 309370b324cSopenharmony_ci const off_t res = File.seek((off_t)offset, (int)seekOrigin); 310370b324cSopenharmony_ci if (res == -1) 311370b324cSopenharmony_ci { 312370b324cSopenharmony_ci const HRESULT hres = GetLastError_HRESULT(); 313370b324cSopenharmony_ci if (newPosition) 314370b324cSopenharmony_ci *newPosition = (UInt64)File.seekToCur(); 315370b324cSopenharmony_ci return hres; 316370b324cSopenharmony_ci } 317370b324cSopenharmony_ci if (newPosition) 318370b324cSopenharmony_ci *newPosition = (UInt64)res; 319370b324cSopenharmony_ci return S_OK; 320370b324cSopenharmony_ci 321370b324cSopenharmony_ci #endif 322370b324cSopenharmony_ci} 323370b324cSopenharmony_ci 324370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetSize(UInt64 *size)) 325370b324cSopenharmony_ci{ 326370b324cSopenharmony_ci return ConvertBoolToHRESULT(File.GetLength(*size)); 327370b324cSopenharmony_ci} 328370b324cSopenharmony_ci 329370b324cSopenharmony_ci#ifdef Z7_FILE_STREAMS_USE_WIN_FILE 330370b324cSopenharmony_ci 331370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) 332370b324cSopenharmony_ci{ 333370b324cSopenharmony_ci if (!_info_WasLoaded) 334370b324cSopenharmony_ci { 335370b324cSopenharmony_ci RINOK(ReloadProps()) 336370b324cSopenharmony_ci } 337370b324cSopenharmony_ci const BY_HANDLE_FILE_INFORMATION &info = _info; 338370b324cSopenharmony_ci /* 339370b324cSopenharmony_ci BY_HANDLE_FILE_INFORMATION info; 340370b324cSopenharmony_ci if (!File.GetFileInformation(&info)) 341370b324cSopenharmony_ci return GetLastError_HRESULT(); 342370b324cSopenharmony_ci */ 343370b324cSopenharmony_ci { 344370b324cSopenharmony_ci if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; 345370b324cSopenharmony_ci if (cTime) *cTime = info.ftCreationTime; 346370b324cSopenharmony_ci if (aTime) *aTime = info.ftLastAccessTime; 347370b324cSopenharmony_ci if (mTime) *mTime = info.ftLastWriteTime; 348370b324cSopenharmony_ci if (attrib) *attrib = info.dwFileAttributes; 349370b324cSopenharmony_ci return S_OK; 350370b324cSopenharmony_ci } 351370b324cSopenharmony_ci} 352370b324cSopenharmony_ci 353370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) 354370b324cSopenharmony_ci{ 355370b324cSopenharmony_ci if (!_info_WasLoaded) 356370b324cSopenharmony_ci { 357370b324cSopenharmony_ci RINOK(ReloadProps()) 358370b324cSopenharmony_ci } 359370b324cSopenharmony_ci const BY_HANDLE_FILE_INFORMATION &info = _info; 360370b324cSopenharmony_ci /* 361370b324cSopenharmony_ci BY_HANDLE_FILE_INFORMATION info; 362370b324cSopenharmony_ci if (!File.GetFileInformation(&info)) 363370b324cSopenharmony_ci return GetLastError_HRESULT(); 364370b324cSopenharmony_ci */ 365370b324cSopenharmony_ci { 366370b324cSopenharmony_ci props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; 367370b324cSopenharmony_ci props->VolID = info.dwVolumeSerialNumber; 368370b324cSopenharmony_ci props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; 369370b324cSopenharmony_ci props->FileID_High = 0; 370370b324cSopenharmony_ci props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1; 371370b324cSopenharmony_ci props->Attrib = info.dwFileAttributes; 372370b324cSopenharmony_ci props->CTime = info.ftCreationTime; 373370b324cSopenharmony_ci props->ATime = info.ftLastAccessTime; 374370b324cSopenharmony_ci props->MTime = info.ftLastWriteTime; 375370b324cSopenharmony_ci return S_OK; 376370b324cSopenharmony_ci } 377370b324cSopenharmony_ci} 378370b324cSopenharmony_ci 379370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) 380370b324cSopenharmony_ci{ 381370b324cSopenharmony_ci if (!_info_WasLoaded) 382370b324cSopenharmony_ci { 383370b324cSopenharmony_ci RINOK(ReloadProps()) 384370b324cSopenharmony_ci } 385370b324cSopenharmony_ci 386370b324cSopenharmony_ci if (!_info_WasLoaded) 387370b324cSopenharmony_ci return S_OK; 388370b324cSopenharmony_ci 389370b324cSopenharmony_ci NWindows::NCOM::CPropVariant prop; 390370b324cSopenharmony_ci 391370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 392370b324cSopenharmony_ci if (File.IsDeviceFile) 393370b324cSopenharmony_ci { 394370b324cSopenharmony_ci switch (propID) 395370b324cSopenharmony_ci { 396370b324cSopenharmony_ci case kpidSize: 397370b324cSopenharmony_ci if (File.SizeDefined) 398370b324cSopenharmony_ci prop = File.Size; 399370b324cSopenharmony_ci break; 400370b324cSopenharmony_ci // case kpidAttrib: prop = (UInt32)0; break; 401370b324cSopenharmony_ci case kpidPosixAttrib: 402370b324cSopenharmony_ci { 403370b324cSopenharmony_ci prop = (UInt32)NWindows::NFile::NFind::NAttributes:: 404370b324cSopenharmony_ci Get_PosixMode_From_WinAttrib(0); 405370b324cSopenharmony_ci /* GNU TAR by default can't extract file with MY_LIN_S_IFBLK attribute 406370b324cSopenharmony_ci so we don't use MY_LIN_S_IFBLK here */ 407370b324cSopenharmony_ci // prop = (UInt32)(MY_LIN_S_IFBLK | 0600); // for debug 408370b324cSopenharmony_ci break; 409370b324cSopenharmony_ci } 410370b324cSopenharmony_ci /* 411370b324cSopenharmony_ci case kpidDeviceMajor: 412370b324cSopenharmony_ci prop = (UInt32)8; // id for SCSI type device (sda) 413370b324cSopenharmony_ci break; 414370b324cSopenharmony_ci case kpidDeviceMinor: 415370b324cSopenharmony_ci prop = (UInt32)0; 416370b324cSopenharmony_ci break; 417370b324cSopenharmony_ci */ 418370b324cSopenharmony_ci } 419370b324cSopenharmony_ci } 420370b324cSopenharmony_ci else 421370b324cSopenharmony_ci #endif 422370b324cSopenharmony_ci { 423370b324cSopenharmony_ci switch (propID) 424370b324cSopenharmony_ci { 425370b324cSopenharmony_ci case kpidSize: 426370b324cSopenharmony_ci { 427370b324cSopenharmony_ci const UInt64 size = (((UInt64)_info.nFileSizeHigh) << 32) + _info.nFileSizeLow; 428370b324cSopenharmony_ci prop = size; 429370b324cSopenharmony_ci break; 430370b324cSopenharmony_ci } 431370b324cSopenharmony_ci case kpidAttrib: prop = (UInt32)_info.dwFileAttributes; break; 432370b324cSopenharmony_ci case kpidCTime: PropVariant_SetFrom_FiTime(prop, _info.ftCreationTime); break; 433370b324cSopenharmony_ci case kpidATime: PropVariant_SetFrom_FiTime(prop, _info.ftLastAccessTime); break; 434370b324cSopenharmony_ci case kpidMTime: PropVariant_SetFrom_FiTime(prop, _info.ftLastWriteTime); break; 435370b324cSopenharmony_ci case kpidPosixAttrib: 436370b324cSopenharmony_ci prop = (UInt32)NWindows::NFile::NFind::NAttributes:: 437370b324cSopenharmony_ci Get_PosixMode_From_WinAttrib(_info.dwFileAttributes); 438370b324cSopenharmony_ci // | (UInt32)(1 << 21); // for debug 439370b324cSopenharmony_ci break; 440370b324cSopenharmony_ci } 441370b324cSopenharmony_ci } 442370b324cSopenharmony_ci prop.Detach(value); 443370b324cSopenharmony_ci return S_OK; 444370b324cSopenharmony_ci} 445370b324cSopenharmony_ci 446370b324cSopenharmony_ci 447370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::ReloadProps()) 448370b324cSopenharmony_ci{ 449370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE 450370b324cSopenharmony_ci if (File.IsDeviceFile) 451370b324cSopenharmony_ci { 452370b324cSopenharmony_ci memset(&_info, 0, sizeof(_info)); 453370b324cSopenharmony_ci if (File.SizeDefined) 454370b324cSopenharmony_ci { 455370b324cSopenharmony_ci _info.nFileSizeHigh = (DWORD)(File.Size >> 32); 456370b324cSopenharmony_ci _info.nFileSizeLow = (DWORD)(File.Size); 457370b324cSopenharmony_ci } 458370b324cSopenharmony_ci _info.nNumberOfLinks = 1; 459370b324cSopenharmony_ci _info_WasLoaded = true; 460370b324cSopenharmony_ci return S_OK; 461370b324cSopenharmony_ci } 462370b324cSopenharmony_ci #endif 463370b324cSopenharmony_ci _info_WasLoaded = File.GetFileInformation(&_info); 464370b324cSopenharmony_ci if (!_info_WasLoaded) 465370b324cSopenharmony_ci return GetLastError_HRESULT(); 466370b324cSopenharmony_ci return S_OK; 467370b324cSopenharmony_ci} 468370b324cSopenharmony_ci 469370b324cSopenharmony_ci 470370b324cSopenharmony_ci#elif !defined(_WIN32) 471370b324cSopenharmony_ci 472370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) 473370b324cSopenharmony_ci{ 474370b324cSopenharmony_ci if (!_info_WasLoaded) 475370b324cSopenharmony_ci { 476370b324cSopenharmony_ci RINOK(ReloadProps()) 477370b324cSopenharmony_ci } 478370b324cSopenharmony_ci const struct stat &st = _info; 479370b324cSopenharmony_ci /* 480370b324cSopenharmony_ci struct stat st; 481370b324cSopenharmony_ci if (File.my_fstat(&st) != 0) 482370b324cSopenharmony_ci return GetLastError_HRESULT(); 483370b324cSopenharmony_ci */ 484370b324cSopenharmony_ci 485370b324cSopenharmony_ci if (size) *size = (UInt64)st.st_size; 486370b324cSopenharmony_ci if (cTime) FiTime_To_FILETIME (ST_CTIME(st), *cTime); 487370b324cSopenharmony_ci if (aTime) FiTime_To_FILETIME (ST_ATIME(st), *aTime); 488370b324cSopenharmony_ci if (mTime) FiTime_To_FILETIME (ST_MTIME(st), *mTime); 489370b324cSopenharmony_ci if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); 490370b324cSopenharmony_ci 491370b324cSopenharmony_ci return S_OK; 492370b324cSopenharmony_ci} 493370b324cSopenharmony_ci 494370b324cSopenharmony_ci// #include <stdio.h> 495370b324cSopenharmony_ci 496370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) 497370b324cSopenharmony_ci{ 498370b324cSopenharmony_ci if (!_info_WasLoaded) 499370b324cSopenharmony_ci { 500370b324cSopenharmony_ci RINOK(ReloadProps()) 501370b324cSopenharmony_ci } 502370b324cSopenharmony_ci const struct stat &st = _info; 503370b324cSopenharmony_ci /* 504370b324cSopenharmony_ci struct stat st; 505370b324cSopenharmony_ci if (File.my_fstat(&st) != 0) 506370b324cSopenharmony_ci return GetLastError_HRESULT(); 507370b324cSopenharmony_ci */ 508370b324cSopenharmony_ci 509370b324cSopenharmony_ci props->Size = (UInt64)st.st_size; 510370b324cSopenharmony_ci /* 511370b324cSopenharmony_ci dev_t stat::st_dev: 512370b324cSopenharmony_ci GCC:Linux long unsigned int : __dev_t 513370b324cSopenharmony_ci Mac: int 514370b324cSopenharmony_ci */ 515370b324cSopenharmony_ci props->VolID = (UInt64)(Int64)st.st_dev; 516370b324cSopenharmony_ci props->FileID_Low = st.st_ino; 517370b324cSopenharmony_ci props->FileID_High = 0; 518370b324cSopenharmony_ci props->NumLinks = (UInt32)st.st_nlink; // we reduce to UInt32 from (nlink_t) that is (unsigned long) 519370b324cSopenharmony_ci props->Attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); 520370b324cSopenharmony_ci 521370b324cSopenharmony_ci FiTime_To_FILETIME (ST_CTIME(st), props->CTime); 522370b324cSopenharmony_ci FiTime_To_FILETIME (ST_ATIME(st), props->ATime); 523370b324cSopenharmony_ci FiTime_To_FILETIME (ST_MTIME(st), props->MTime); 524370b324cSopenharmony_ci 525370b324cSopenharmony_ci /* 526370b324cSopenharmony_ci printf("\nGetProps2() NumLinks=%d = st_dev=%d st_ino = %d\n" 527370b324cSopenharmony_ci , (unsigned)(props->NumLinks) 528370b324cSopenharmony_ci , (unsigned)(st.st_dev) 529370b324cSopenharmony_ci , (unsigned)(st.st_ino) 530370b324cSopenharmony_ci ); 531370b324cSopenharmony_ci */ 532370b324cSopenharmony_ci 533370b324cSopenharmony_ci return S_OK; 534370b324cSopenharmony_ci} 535370b324cSopenharmony_ci 536370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) 537370b324cSopenharmony_ci{ 538370b324cSopenharmony_ci if (!_info_WasLoaded) 539370b324cSopenharmony_ci { 540370b324cSopenharmony_ci RINOK(ReloadProps()) 541370b324cSopenharmony_ci } 542370b324cSopenharmony_ci 543370b324cSopenharmony_ci if (!_info_WasLoaded) 544370b324cSopenharmony_ci return S_OK; 545370b324cSopenharmony_ci 546370b324cSopenharmony_ci const struct stat &st = _info; 547370b324cSopenharmony_ci 548370b324cSopenharmony_ci NWindows::NCOM::CPropVariant prop; 549370b324cSopenharmony_ci { 550370b324cSopenharmony_ci switch (propID) 551370b324cSopenharmony_ci { 552370b324cSopenharmony_ci case kpidSize: prop = (UInt64)st.st_size; break; 553370b324cSopenharmony_ci case kpidAttrib: 554370b324cSopenharmony_ci prop = (UInt32)NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); 555370b324cSopenharmony_ci break; 556370b324cSopenharmony_ci case kpidCTime: PropVariant_SetFrom_FiTime(prop, ST_CTIME(st)); break; 557370b324cSopenharmony_ci case kpidATime: PropVariant_SetFrom_FiTime(prop, ST_ATIME(st)); break; 558370b324cSopenharmony_ci case kpidMTime: PropVariant_SetFrom_FiTime(prop, ST_MTIME(st)); break; 559370b324cSopenharmony_ci case kpidPosixAttrib: prop = (UInt32)st.st_mode; break; 560370b324cSopenharmony_ci 561370b324cSopenharmony_ci #if defined(__APPLE__) 562370b324cSopenharmony_ci #pragma GCC diagnostic push 563370b324cSopenharmony_ci #pragma GCC diagnostic ignored "-Wsign-conversion" 564370b324cSopenharmony_ci #endif 565370b324cSopenharmony_ci 566370b324cSopenharmony_ci case kpidDeviceMajor: 567370b324cSopenharmony_ci { 568370b324cSopenharmony_ci // printf("\nst.st_rdev = %d\n", st.st_rdev); 569370b324cSopenharmony_ci if (S_ISCHR(st.st_mode) || 570370b324cSopenharmony_ci S_ISBLK(st.st_mode)) 571370b324cSopenharmony_ci prop = (UInt32)(major(st.st_rdev)); // + 1000); 572370b324cSopenharmony_ci // prop = (UInt32)12345678; // for debug 573370b324cSopenharmony_ci break; 574370b324cSopenharmony_ci } 575370b324cSopenharmony_ci 576370b324cSopenharmony_ci case kpidDeviceMinor: 577370b324cSopenharmony_ci if (S_ISCHR(st.st_mode) || 578370b324cSopenharmony_ci S_ISBLK(st.st_mode)) 579370b324cSopenharmony_ci prop = (UInt32)(minor(st.st_rdev)); // + 100); 580370b324cSopenharmony_ci // prop = (UInt32)(st.st_rdev); // for debug 581370b324cSopenharmony_ci // printf("\nst.st_rdev = %d\n", st.st_rdev); 582370b324cSopenharmony_ci // prop = (UInt32)123456789; // for debug 583370b324cSopenharmony_ci break; 584370b324cSopenharmony_ci 585370b324cSopenharmony_ci #if defined(__APPLE__) 586370b324cSopenharmony_ci #pragma GCC diagnostic pop 587370b324cSopenharmony_ci #endif 588370b324cSopenharmony_ci 589370b324cSopenharmony_ci /* 590370b324cSopenharmony_ci case kpidDevice: 591370b324cSopenharmony_ci if (S_ISCHR(st.st_mode) || 592370b324cSopenharmony_ci S_ISBLK(st.st_mode)) 593370b324cSopenharmony_ci prop = (UInt64)(st.st_rdev); 594370b324cSopenharmony_ci break; 595370b324cSopenharmony_ci */ 596370b324cSopenharmony_ci 597370b324cSopenharmony_ci case kpidUserId: 598370b324cSopenharmony_ci { 599370b324cSopenharmony_ci if (StoreOwnerId) 600370b324cSopenharmony_ci prop = (UInt32)st.st_uid; 601370b324cSopenharmony_ci break; 602370b324cSopenharmony_ci } 603370b324cSopenharmony_ci case kpidGroupId: 604370b324cSopenharmony_ci { 605370b324cSopenharmony_ci if (StoreOwnerId) 606370b324cSopenharmony_ci prop = (UInt32)st.st_gid; 607370b324cSopenharmony_ci break; 608370b324cSopenharmony_ci } 609370b324cSopenharmony_ci case kpidUser: 610370b324cSopenharmony_ci { 611370b324cSopenharmony_ci if (StoreOwnerName) 612370b324cSopenharmony_ci { 613370b324cSopenharmony_ci const uid_t uid = st.st_uid; 614370b324cSopenharmony_ci { 615370b324cSopenharmony_ci if (!OwnerName.IsEmpty() && _uid == uid) 616370b324cSopenharmony_ci prop = OwnerName; 617370b324cSopenharmony_ci else 618370b324cSopenharmony_ci { 619370b324cSopenharmony_ci const passwd *pw = getpwuid(uid); 620370b324cSopenharmony_ci if (pw) 621370b324cSopenharmony_ci { 622370b324cSopenharmony_ci // we can use utf-8 here. 623370b324cSopenharmony_ci // prop = pw->pw_name; 624370b324cSopenharmony_ci } 625370b324cSopenharmony_ci } 626370b324cSopenharmony_ci } 627370b324cSopenharmony_ci } 628370b324cSopenharmony_ci break; 629370b324cSopenharmony_ci } 630370b324cSopenharmony_ci case kpidGroup: 631370b324cSopenharmony_ci { 632370b324cSopenharmony_ci if (StoreOwnerName) 633370b324cSopenharmony_ci { 634370b324cSopenharmony_ci const uid_t gid = st.st_gid; 635370b324cSopenharmony_ci { 636370b324cSopenharmony_ci if (!OwnerGroup.IsEmpty() && _gid == gid) 637370b324cSopenharmony_ci prop = OwnerGroup; 638370b324cSopenharmony_ci else 639370b324cSopenharmony_ci { 640370b324cSopenharmony_ci const group *gr = getgrgid(gid); 641370b324cSopenharmony_ci if (gr) 642370b324cSopenharmony_ci { 643370b324cSopenharmony_ci // we can use utf-8 here. 644370b324cSopenharmony_ci // prop = gr->gr_name; 645370b324cSopenharmony_ci } 646370b324cSopenharmony_ci } 647370b324cSopenharmony_ci } 648370b324cSopenharmony_ci } 649370b324cSopenharmony_ci break; 650370b324cSopenharmony_ci } 651370b324cSopenharmony_ci } 652370b324cSopenharmony_ci } 653370b324cSopenharmony_ci prop.Detach(value); 654370b324cSopenharmony_ci return S_OK; 655370b324cSopenharmony_ci} 656370b324cSopenharmony_ci 657370b324cSopenharmony_ci 658370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::ReloadProps()) 659370b324cSopenharmony_ci{ 660370b324cSopenharmony_ci _info_WasLoaded = (File.my_fstat(&_info) == 0); 661370b324cSopenharmony_ci if (!_info_WasLoaded) 662370b324cSopenharmony_ci return GetLastError_HRESULT(); 663370b324cSopenharmony_ci return S_OK; 664370b324cSopenharmony_ci} 665370b324cSopenharmony_ci 666370b324cSopenharmony_ci#endif 667370b324cSopenharmony_ci 668370b324cSopenharmony_ci 669370b324cSopenharmony_ci 670370b324cSopenharmony_ci 671370b324cSopenharmony_ci////////////////////////// 672370b324cSopenharmony_ci// COutFileStream 673370b324cSopenharmony_ci 674370b324cSopenharmony_ciHRESULT COutFileStream::Close() 675370b324cSopenharmony_ci{ 676370b324cSopenharmony_ci return ConvertBoolToHRESULT(File.Close()); 677370b324cSopenharmony_ci} 678370b324cSopenharmony_ci 679370b324cSopenharmony_ciZ7_COM7F_IMF(COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) 680370b324cSopenharmony_ci{ 681370b324cSopenharmony_ci #ifdef Z7_FILE_STREAMS_USE_WIN_FILE 682370b324cSopenharmony_ci 683370b324cSopenharmony_ci UInt32 realProcessedSize; 684370b324cSopenharmony_ci const bool result = File.Write(data, size, realProcessedSize); 685370b324cSopenharmony_ci ProcessedSize += realProcessedSize; 686370b324cSopenharmony_ci if (processedSize) 687370b324cSopenharmony_ci *processedSize = realProcessedSize; 688370b324cSopenharmony_ci return ConvertBoolToHRESULT(result); 689370b324cSopenharmony_ci 690370b324cSopenharmony_ci #else 691370b324cSopenharmony_ci 692370b324cSopenharmony_ci if (processedSize) 693370b324cSopenharmony_ci *processedSize = 0; 694370b324cSopenharmony_ci size_t realProcessedSize; 695370b324cSopenharmony_ci const ssize_t res = File.write_full(data, (size_t)size, realProcessedSize); 696370b324cSopenharmony_ci ProcessedSize += realProcessedSize; 697370b324cSopenharmony_ci if (processedSize) 698370b324cSopenharmony_ci *processedSize = (UInt32)realProcessedSize; 699370b324cSopenharmony_ci if (res == -1) 700370b324cSopenharmony_ci return GetLastError_HRESULT(); 701370b324cSopenharmony_ci return S_OK; 702370b324cSopenharmony_ci 703370b324cSopenharmony_ci #endif 704370b324cSopenharmony_ci} 705370b324cSopenharmony_ci 706370b324cSopenharmony_ciZ7_COM7F_IMF(COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) 707370b324cSopenharmony_ci{ 708370b324cSopenharmony_ci if (seekOrigin >= 3) 709370b324cSopenharmony_ci return STG_E_INVALIDFUNCTION; 710370b324cSopenharmony_ci 711370b324cSopenharmony_ci #ifdef Z7_FILE_STREAMS_USE_WIN_FILE 712370b324cSopenharmony_ci 713370b324cSopenharmony_ci UInt64 realNewPosition = 0; 714370b324cSopenharmony_ci const bool result = File.Seek(offset, seekOrigin, realNewPosition); 715370b324cSopenharmony_ci if (newPosition) 716370b324cSopenharmony_ci *newPosition = realNewPosition; 717370b324cSopenharmony_ci return ConvertBoolToHRESULT(result); 718370b324cSopenharmony_ci 719370b324cSopenharmony_ci #else 720370b324cSopenharmony_ci 721370b324cSopenharmony_ci const off_t res = File.seek((off_t)offset, (int)seekOrigin); 722370b324cSopenharmony_ci if (res == -1) 723370b324cSopenharmony_ci return GetLastError_HRESULT(); 724370b324cSopenharmony_ci if (newPosition) 725370b324cSopenharmony_ci *newPosition = (UInt64)res; 726370b324cSopenharmony_ci return S_OK; 727370b324cSopenharmony_ci 728370b324cSopenharmony_ci #endif 729370b324cSopenharmony_ci} 730370b324cSopenharmony_ci 731370b324cSopenharmony_ciZ7_COM7F_IMF(COutFileStream::SetSize(UInt64 newSize)) 732370b324cSopenharmony_ci{ 733370b324cSopenharmony_ci return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize)); 734370b324cSopenharmony_ci} 735370b324cSopenharmony_ci 736370b324cSopenharmony_ciHRESULT COutFileStream::GetSize(UInt64 *size) 737370b324cSopenharmony_ci{ 738370b324cSopenharmony_ci return ConvertBoolToHRESULT(File.GetLength(*size)); 739370b324cSopenharmony_ci} 740370b324cSopenharmony_ci 741370b324cSopenharmony_ci#ifdef UNDER_CE 742370b324cSopenharmony_ci 743370b324cSopenharmony_ciZ7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) 744370b324cSopenharmony_ci{ 745370b324cSopenharmony_ci size_t s2 = fwrite(data, 1, size, stdout); 746370b324cSopenharmony_ci if (processedSize) 747370b324cSopenharmony_ci *processedSize = s2; 748370b324cSopenharmony_ci return (s2 == size) ? S_OK : E_FAIL; 749370b324cSopenharmony_ci} 750370b324cSopenharmony_ci 751370b324cSopenharmony_ci#else 752370b324cSopenharmony_ci 753370b324cSopenharmony_ciZ7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) 754370b324cSopenharmony_ci{ 755370b324cSopenharmony_ci if (processedSize) 756370b324cSopenharmony_ci *processedSize = 0; 757370b324cSopenharmony_ci 758370b324cSopenharmony_ci #ifdef _WIN32 759370b324cSopenharmony_ci 760370b324cSopenharmony_ci UInt32 realProcessedSize; 761370b324cSopenharmony_ci BOOL res = TRUE; 762370b324cSopenharmony_ci if (size > 0) 763370b324cSopenharmony_ci { 764370b324cSopenharmony_ci // Seems that Windows doesn't like big amounts writing to stdout. 765370b324cSopenharmony_ci // So we limit portions by 32KB. 766370b324cSopenharmony_ci UInt32 sizeTemp = (1 << 15); 767370b324cSopenharmony_ci if (sizeTemp > size) 768370b324cSopenharmony_ci sizeTemp = size; 769370b324cSopenharmony_ci res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), 770370b324cSopenharmony_ci data, sizeTemp, (DWORD *)&realProcessedSize, NULL); 771370b324cSopenharmony_ci _size += realProcessedSize; 772370b324cSopenharmony_ci size -= realProcessedSize; 773370b324cSopenharmony_ci data = (const void *)((const Byte *)data + realProcessedSize); 774370b324cSopenharmony_ci if (processedSize) 775370b324cSopenharmony_ci *processedSize += realProcessedSize; 776370b324cSopenharmony_ci } 777370b324cSopenharmony_ci return ConvertBoolToHRESULT(res != FALSE); 778370b324cSopenharmony_ci 779370b324cSopenharmony_ci #else 780370b324cSopenharmony_ci 781370b324cSopenharmony_ci ssize_t res; 782370b324cSopenharmony_ci 783370b324cSopenharmony_ci do 784370b324cSopenharmony_ci { 785370b324cSopenharmony_ci res = write(1, data, (size_t)size); 786370b324cSopenharmony_ci } 787370b324cSopenharmony_ci while (res < 0 && (errno == EINTR)); 788370b324cSopenharmony_ci 789370b324cSopenharmony_ci if (res == -1) 790370b324cSopenharmony_ci return GetLastError_HRESULT(); 791370b324cSopenharmony_ci 792370b324cSopenharmony_ci _size += (size_t)res; 793370b324cSopenharmony_ci if (processedSize) 794370b324cSopenharmony_ci *processedSize = (UInt32)res; 795370b324cSopenharmony_ci return S_OK; 796370b324cSopenharmony_ci 797370b324cSopenharmony_ci #endif 798370b324cSopenharmony_ci} 799370b324cSopenharmony_ci 800370b324cSopenharmony_ci#endif 801