1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// FileStreams.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _WIN32 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <fcntl.h> 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <unistd.h> 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <errno.h> 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef SUPPORT_DEVICE_FILE 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/Alloc.h" 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/Defs.h" 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "FileStreams.h" 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline HRESULT ConvertBoolToHRESULT(bool result) 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _WIN32 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result) 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DWORD lastError = ::GetLastError(); 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lastError == 0) 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return HRESULT_FROM_WIN32(lastError); 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result ? S_OK: E_FAIL; 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 33baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kClusterSize = 1 << 18; 34baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCInFileStream::CInFileStream(): 35f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka #ifdef SUPPORT_DEVICE_FILE 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync VirtPos(0), 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync PhyPos(0), 38cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Buf(0), 39cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky BufSize(0), 40f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka #endif 41f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka SupportHardLinks(false), 42f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Callback(NULL), 43f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CallbackRef(0) 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 47baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCInFileStream::~CInFileStream() 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef SUPPORT_DEVICE_FILE 50cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky MidFree(Buf); 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 52f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 53f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (Callback) 54f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Callback->InFileStream_On_Destroy(CallbackRef); 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 57baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef USE_WIN_FILE 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef SUPPORT_DEVICE_FILE 62cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = 0; 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size == 0) 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (File.IsDeviceFile) 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 68cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (File.SizeDefined) 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 70cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (VirtPos >= File.Size) 71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return VirtPos == File.Size ? S_OK : E_FAIL; 72cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 rem = File.Size - VirtPos; 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > rem) 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size = (UInt32)rem; 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt32 mask = kClusterSize - 1; 79cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const UInt64 mask2 = ~(UInt64)mask; 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 alignedPos = VirtPos & mask2; 81cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (BufSize > 0 && BufStartPos == alignedPos) 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 pos = (UInt32)VirtPos & mask; 84cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (pos >= BufSize) 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 86cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 rem = MyMin(BufSize - pos, size); 87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky memcpy(data, Buf + pos, rem); 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync VirtPos += rem; 89cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize += rem; 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 94cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool useBuf = false; 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 ) 96cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky useBuf = true; 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 end = VirtPos + size; 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((end & mask) != 0) 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync end &= mask2; 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (end <= VirtPos) 104cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky useBuf = true; 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size = (UInt32)(end - VirtPos); 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!useBuf) 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (alignedPos != PhyPos) 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 realNewPosition; 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition); 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!result) 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(result); 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync PhyPos = realNewPosition; 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 120cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky BufStartPos = alignedPos; 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 readSize = kClusterSize; 122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (File.SizeDefined) 123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize); 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 125cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!Buf) 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Buf = (Byte *)MidAlloc(kClusterSize); 128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!Buf) 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_OUTOFMEMORY; 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 131cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool result = File.Read1(Buf, readSize, BufSize); 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!result) 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(result); 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (BufSize == 0) 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 137cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky PhyPos += BufSize; 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (VirtPos != PhyPos) 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 realNewPosition; 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition); 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!result) 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(result); 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync PhyPos = VirtPos = realNewPosition; 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 realProcessedSize; 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool result = File.ReadPart(data, size, realProcessedSize); 153cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = realProcessedSize; 155f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef SUPPORT_DEVICE_FILE 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync VirtPos += realProcessedSize; 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync PhyPos += realProcessedSize; 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 160f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 161f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (result) 162f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return S_OK; 163f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 164f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka { 165f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka DWORD error = ::GetLastError(); 166f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 167f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (Callback) 168f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return Callback->InFileStream_On_Error(CallbackRef, error); 169f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (error == 0) 170f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return E_FAIL; 171f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 172f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return HRESULT_FROM_WIN32(error); 173f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka } 174f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = 0; 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ssize_t res = File.Read(data, (size_t)size); 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == -1) 181f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka { 182f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (Callback) 183f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return Callback->InFileStream_On_Error(CallbackRef, E_FAIL); 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 185f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka } 186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = (UInt32)res; 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef UNDER_CE 194baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t s2 = fread(data, 1, size, stdin); 197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky int error = ferror(stdin); 198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = s2; 200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (s2 <= size && error == 0) 201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return E_FAIL; 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else 205baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _WIN32 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DWORD realProcessedSize; 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 sizeTemp = (1 << 20); 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (sizeTemp > size) 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizeTemp = size; 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL); 214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = realProcessedSize; 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(res != FALSE); 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = 0; 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ssize_t res; 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = read(0, data, (size_t)size); 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (res < 0 && (errno == EINTR)); 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == -1) 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 232cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = (UInt32)res; 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 241cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (seekOrigin >= 3) 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return STG_E_INVALIDFUNCTION; 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef USE_WIN_FILE 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef SUPPORT_DEVICE_FILE 249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END)) 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky switch (seekOrigin) 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case STREAM_SEEK_SET: break; 254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case STREAM_SEEK_CUR: offset += VirtPos; break; 255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case STREAM_SEEK_END: offset += File.Size; break; 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: return STG_E_INVALIDFUNCTION; 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (offset < 0) 259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; 260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky VirtPos = offset; 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (newPosition) 262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky *newPosition = offset; 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 realNewPosition; 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool result = File.Seek(offset, seekOrigin, realNewPosition); 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef SUPPORT_DEVICE_FILE 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync PhyPos = VirtPos = realNewPosition; 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (newPosition) 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *newPosition = realNewPosition; 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(result); 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky off_t res = File.Seek((off_t)offset, seekOrigin); 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == -1) 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (newPosition) 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *newPosition = (UInt64)res; 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 290baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CInFileStream::GetSize(UInt64 *size) 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(File.GetLength(*size)); 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifdef USE_WIN_FILE 296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) 298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky BY_HANDLE_FILE_INFORMATION info; 300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (File.GetFileInformation(&info)) 301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; 303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (cTime) *cTime = info.ftCreationTime; 304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (aTime) *aTime = info.ftLastAccessTime; 305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (mTime) *mTime = info.ftLastWriteTime; 306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (attrib) *attrib = info.dwFileAttributes; 307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return GetLastError(); 310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) 313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky BY_HANDLE_FILE_INFORMATION info; 315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (File.GetFileInformation(&info)) 316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; 318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->VolID = info.dwVolumeSerialNumber; 319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; 320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->FileID_High = 0; 321cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1; 322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->Attrib = info.dwFileAttributes; 323cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->CTime = info.ftCreationTime; 324cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->ATime = info.ftLastAccessTime; 325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky props->MTime = info.ftLastWriteTime; 326cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 328cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return GetLastError(); 329cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync////////////////////////// 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// COutFileStream 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 336baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutFileStream::Close() 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(File.Close()); 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 341baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef USE_WIN_FILE 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 realProcessedSize; 346f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka bool result = File.Write(data, size, realProcessedSize); 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ProcessedSize += realProcessedSize; 348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = realProcessedSize; 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(result); 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = 0; 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ssize_t res = File.Write(data, (size_t)size); 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == -1) 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 359cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = (UInt32)res; 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ProcessedSize += res; 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 367baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (seekOrigin >= 3) 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return STG_E_INVALIDFUNCTION; 371f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef USE_WIN_FILE 373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 realNewPosition; 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool result = File.Seek(offset, seekOrigin, realNewPosition); 376cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (newPosition) 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *newPosition = realNewPosition; 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(result); 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 382cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky off_t res = File.Seek((off_t)offset, seekOrigin); 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == -1) 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 385cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (newPosition) 386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *newPosition = (UInt64)res; 387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 392baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutFileStream::SetSize(UInt64 newSize) 393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef USE_WIN_FILE 395f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 currentPos; 397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!File.Seek(0, FILE_CURRENT, currentPos)) 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool result = File.SetLength(newSize); 400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 currentPos2; 401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result = result && File.Seek(currentPos, currentPos2); 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result ? S_OK : E_FAIL; 403f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 405f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 407f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 411f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo OsakaHRESULT COutFileStream::GetSize(UInt64 *size) 412f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka{ 413f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return ConvertBoolToHRESULT(File.GetLength(*size)); 414f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka} 415f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef UNDER_CE 417f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 418baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) 419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t s2 = fwrite(data, 1, size, stdout); 421cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = s2; 423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return (s2 == size) ? S_OK : E_FAIL; 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 425f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else 427f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 428baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 430cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = 0; 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _WIN32 434f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 realProcessedSize; 436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BOOL res = TRUE; 437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > 0) 438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // Seems that Windows doesn't like big amounts writing to stdout. 440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // So we limit portions by 32KB. 441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 sizeTemp = (1 << 15); 442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (sizeTemp > size) 443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizeTemp = size; 444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), 445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync data, sizeTemp, (DWORD *)&realProcessedSize, NULL); 446f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _size += realProcessedSize; 447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size -= realProcessedSize; 448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync data = (const void *)((const Byte *)data + realProcessedSize); 449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize += realProcessedSize; 451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ConvertBoolToHRESULT(res != FALSE); 453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ssize_t res; 457f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = write(1, data, (size_t)size); 461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (res < 0 && (errno == EINTR)); 463f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == -1) 465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 466f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 467f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _size += (size_t)res; 468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processedSize) 469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = (UInt32)res; 470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 476