xref: /aosp_15_r20/external/lzma/CPP/7zip/Common/FileStreams.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // FileStreams.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
8*f6dc9357SAndroid Build Coastguard Worker #include <fcntl.h>
9*f6dc9357SAndroid Build Coastguard Worker #include <unistd.h>
10*f6dc9357SAndroid Build Coastguard Worker #include <errno.h>
11*f6dc9357SAndroid Build Coastguard Worker #include <grp.h>
12*f6dc9357SAndroid Build Coastguard Worker #include <pwd.h>
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker /*
15*f6dc9357SAndroid Build Coastguard Worker inclusion of <sys/sysmacros.h> by <sys/types.h> is deprecated since glibc 2.25.
16*f6dc9357SAndroid Build Coastguard Worker Since glibc 2.3.3, macros have been aliases for three GNU-specific
17*f6dc9357SAndroid Build Coastguard Worker functions: gnu_dev_makedev(), gnu_dev_major(), and gnu_dev_minor()
18*f6dc9357SAndroid Build Coastguard Worker 
19*f6dc9357SAndroid Build Coastguard Worker Warning in GCC:
20*f6dc9357SAndroid Build Coastguard Worker In the GNU C Library, "major" is defined by <sys/sysmacros.h>.
21*f6dc9357SAndroid Build Coastguard Worker For historical compatibility, it is currently defined by
22*f6dc9357SAndroid Build Coastguard Worker <sys/types.h> as well, but we plan to remove this soon.
23*f6dc9357SAndroid Build Coastguard Worker To use "major", include <sys/sysmacros.h> directly.
24*f6dc9357SAndroid Build Coastguard Worker If you did not intend to use a system-defined macro "major",
25*f6dc9357SAndroid Build Coastguard Worker you should undefine it after including <sys/types.h>
26*f6dc9357SAndroid Build Coastguard Worker */
27*f6dc9357SAndroid Build Coastguard Worker // for major()/minor():
28*f6dc9357SAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__DragonFly__) || \
29*f6dc9357SAndroid Build Coastguard Worker     defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
30*f6dc9357SAndroid Build Coastguard Worker #include <sys/types.h>
31*f6dc9357SAndroid Build Coastguard Worker #else
32*f6dc9357SAndroid Build Coastguard Worker #include <sys/sysmacros.h>
33*f6dc9357SAndroid Build Coastguard Worker #endif
34*f6dc9357SAndroid Build Coastguard Worker 
35*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/FileFind.h"
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_DEVICE_FILE
40*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/Alloc.h"
41*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/Defs.h"
42*f6dc9357SAndroid Build Coastguard Worker #endif
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker #include "../PropID.h"
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker #include "FileStreams.h"
47*f6dc9357SAndroid Build Coastguard Worker 
GetLastError_HRESULT()48*f6dc9357SAndroid Build Coastguard Worker static inline HRESULT GetLastError_HRESULT()
49*f6dc9357SAndroid Build Coastguard Worker {
50*f6dc9357SAndroid Build Coastguard Worker   DWORD lastError = ::GetLastError();
51*f6dc9357SAndroid Build Coastguard Worker   if (lastError == 0)
52*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
53*f6dc9357SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(lastError);
54*f6dc9357SAndroid Build Coastguard Worker }
55*f6dc9357SAndroid Build Coastguard Worker 
ConvertBoolToHRESULT(bool result)56*f6dc9357SAndroid Build Coastguard Worker static inline HRESULT ConvertBoolToHRESULT(bool result)
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker   if (result)
59*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
60*f6dc9357SAndroid Build Coastguard Worker   return GetLastError_HRESULT();
61*f6dc9357SAndroid Build Coastguard Worker }
62*f6dc9357SAndroid Build Coastguard Worker 
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_DEVICE_FILE
65*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kClusterSize = 1 << 18;
66*f6dc9357SAndroid Build Coastguard Worker #endif
67*f6dc9357SAndroid Build Coastguard Worker 
CInFileStream()68*f6dc9357SAndroid Build Coastguard Worker CInFileStream::CInFileStream():
69*f6dc9357SAndroid Build Coastguard Worker  #ifdef Z7_DEVICE_FILE
70*f6dc9357SAndroid Build Coastguard Worker   VirtPos(0),
71*f6dc9357SAndroid Build Coastguard Worker   PhyPos(0),
72*f6dc9357SAndroid Build Coastguard Worker   Buf(NULL),
73*f6dc9357SAndroid Build Coastguard Worker   BufSize(0),
74*f6dc9357SAndroid Build Coastguard Worker  #endif
75*f6dc9357SAndroid Build Coastguard Worker  #ifndef _WIN32
76*f6dc9357SAndroid Build Coastguard Worker   _uid(0),
77*f6dc9357SAndroid Build Coastguard Worker   _gid(0),
78*f6dc9357SAndroid Build Coastguard Worker   StoreOwnerId(false),
79*f6dc9357SAndroid Build Coastguard Worker   StoreOwnerName(false),
80*f6dc9357SAndroid Build Coastguard Worker  #endif
81*f6dc9357SAndroid Build Coastguard Worker   _info_WasLoaded(false),
82*f6dc9357SAndroid Build Coastguard Worker   SupportHardLinks(false),
83*f6dc9357SAndroid Build Coastguard Worker   Callback(NULL),
84*f6dc9357SAndroid Build Coastguard Worker   CallbackRef(0)
85*f6dc9357SAndroid Build Coastguard Worker {
86*f6dc9357SAndroid Build Coastguard Worker }
87*f6dc9357SAndroid Build Coastguard Worker 
~CInFileStream()88*f6dc9357SAndroid Build Coastguard Worker CInFileStream::~CInFileStream()
89*f6dc9357SAndroid Build Coastguard Worker {
90*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_DEVICE_FILE
91*f6dc9357SAndroid Build Coastguard Worker   MidFree(Buf);
92*f6dc9357SAndroid Build Coastguard Worker   #endif
93*f6dc9357SAndroid Build Coastguard Worker 
94*f6dc9357SAndroid Build Coastguard Worker   if (Callback)
95*f6dc9357SAndroid Build Coastguard Worker     Callback->InFileStream_On_Destroy(this, CallbackRef);
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::Read (void * data,UInt32 size,UInt32 * processedSize))98*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize))
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker   // printf("\nCInFileStream::Read size=%d, VirtPos=%8d\n", (unsigned)size, (int)VirtPos);
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_DEVICE_FILE
105*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
106*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
107*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
108*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
109*f6dc9357SAndroid Build Coastguard Worker   if (File.IsDeviceFile)
110*f6dc9357SAndroid Build Coastguard Worker   {
111*f6dc9357SAndroid Build Coastguard Worker     if (File.SizeDefined)
112*f6dc9357SAndroid Build Coastguard Worker     {
113*f6dc9357SAndroid Build Coastguard Worker       if (VirtPos >= File.Size)
114*f6dc9357SAndroid Build Coastguard Worker         return VirtPos == File.Size ? S_OK : E_FAIL;
115*f6dc9357SAndroid Build Coastguard Worker       const UInt64 rem = File.Size - VirtPos;
116*f6dc9357SAndroid Build Coastguard Worker       if (size > rem)
117*f6dc9357SAndroid Build Coastguard Worker         size = (UInt32)rem;
118*f6dc9357SAndroid Build Coastguard Worker     }
119*f6dc9357SAndroid Build Coastguard Worker     for (;;)
120*f6dc9357SAndroid Build Coastguard Worker     {
121*f6dc9357SAndroid Build Coastguard Worker       const UInt32 mask = kClusterSize - 1;
122*f6dc9357SAndroid Build Coastguard Worker       const UInt64 mask2 = ~(UInt64)mask;
123*f6dc9357SAndroid Build Coastguard Worker       const UInt64 alignedPos = VirtPos & mask2;
124*f6dc9357SAndroid Build Coastguard Worker       if (BufSize > 0 && BufStartPos == alignedPos)
125*f6dc9357SAndroid Build Coastguard Worker       {
126*f6dc9357SAndroid Build Coastguard Worker         const UInt32 pos = (UInt32)VirtPos & mask;
127*f6dc9357SAndroid Build Coastguard Worker         if (pos >= BufSize)
128*f6dc9357SAndroid Build Coastguard Worker           return S_OK;
129*f6dc9357SAndroid Build Coastguard Worker         const UInt32 rem = MyMin(BufSize - pos, size);
130*f6dc9357SAndroid Build Coastguard Worker         memcpy(data, Buf + pos, rem);
131*f6dc9357SAndroid Build Coastguard Worker         VirtPos += rem;
132*f6dc9357SAndroid Build Coastguard Worker         if (processedSize)
133*f6dc9357SAndroid Build Coastguard Worker           *processedSize += rem;
134*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
135*f6dc9357SAndroid Build Coastguard Worker       }
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker       bool useBuf = false;
138*f6dc9357SAndroid Build Coastguard Worker       if ((VirtPos & mask) != 0 || ((size_t)(ptrdiff_t)data & mask) != 0 )
139*f6dc9357SAndroid Build Coastguard Worker         useBuf = true;
140*f6dc9357SAndroid Build Coastguard Worker       else
141*f6dc9357SAndroid Build Coastguard Worker       {
142*f6dc9357SAndroid Build Coastguard Worker         UInt64 end = VirtPos + size;
143*f6dc9357SAndroid Build Coastguard Worker         if ((end & mask) != 0)
144*f6dc9357SAndroid Build Coastguard Worker         {
145*f6dc9357SAndroid Build Coastguard Worker           end &= mask2;
146*f6dc9357SAndroid Build Coastguard Worker           if (end <= VirtPos)
147*f6dc9357SAndroid Build Coastguard Worker             useBuf = true;
148*f6dc9357SAndroid Build Coastguard Worker           else
149*f6dc9357SAndroid Build Coastguard Worker             size = (UInt32)(end - VirtPos);
150*f6dc9357SAndroid Build Coastguard Worker         }
151*f6dc9357SAndroid Build Coastguard Worker       }
152*f6dc9357SAndroid Build Coastguard Worker       if (!useBuf)
153*f6dc9357SAndroid Build Coastguard Worker         break;
154*f6dc9357SAndroid Build Coastguard Worker       if (alignedPos != PhyPos)
155*f6dc9357SAndroid Build Coastguard Worker       {
156*f6dc9357SAndroid Build Coastguard Worker         UInt64 realNewPosition;
157*f6dc9357SAndroid Build Coastguard Worker         const bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition);
158*f6dc9357SAndroid Build Coastguard Worker         if (!result)
159*f6dc9357SAndroid Build Coastguard Worker           return ConvertBoolToHRESULT(result);
160*f6dc9357SAndroid Build Coastguard Worker         PhyPos = realNewPosition;
161*f6dc9357SAndroid Build Coastguard Worker       }
162*f6dc9357SAndroid Build Coastguard Worker 
163*f6dc9357SAndroid Build Coastguard Worker       BufStartPos = alignedPos;
164*f6dc9357SAndroid Build Coastguard Worker       UInt32 readSize = kClusterSize;
165*f6dc9357SAndroid Build Coastguard Worker       if (File.SizeDefined)
166*f6dc9357SAndroid Build Coastguard Worker         readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize);
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker       if (!Buf)
169*f6dc9357SAndroid Build Coastguard Worker       {
170*f6dc9357SAndroid Build Coastguard Worker         Buf = (Byte *)MidAlloc(kClusterSize);
171*f6dc9357SAndroid Build Coastguard Worker         if (!Buf)
172*f6dc9357SAndroid Build Coastguard Worker           return E_OUTOFMEMORY;
173*f6dc9357SAndroid Build Coastguard Worker       }
174*f6dc9357SAndroid Build Coastguard Worker       const bool result = File.Read1(Buf, readSize, BufSize);
175*f6dc9357SAndroid Build Coastguard Worker       if (!result)
176*f6dc9357SAndroid Build Coastguard Worker         return ConvertBoolToHRESULT(result);
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker       if (BufSize == 0)
179*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
180*f6dc9357SAndroid Build Coastguard Worker       PhyPos += BufSize;
181*f6dc9357SAndroid Build Coastguard Worker     }
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker     if (VirtPos != PhyPos)
184*f6dc9357SAndroid Build Coastguard Worker     {
185*f6dc9357SAndroid Build Coastguard Worker       UInt64 realNewPosition;
186*f6dc9357SAndroid Build Coastguard Worker       bool result = File.Seek((Int64)VirtPos, FILE_BEGIN, realNewPosition);
187*f6dc9357SAndroid Build Coastguard Worker       if (!result)
188*f6dc9357SAndroid Build Coastguard Worker         return ConvertBoolToHRESULT(result);
189*f6dc9357SAndroid Build Coastguard Worker       PhyPos = VirtPos = realNewPosition;
190*f6dc9357SAndroid Build Coastguard Worker     }
191*f6dc9357SAndroid Build Coastguard Worker   }
192*f6dc9357SAndroid Build Coastguard Worker   #endif
193*f6dc9357SAndroid Build Coastguard Worker 
194*f6dc9357SAndroid Build Coastguard Worker   UInt32 realProcessedSize;
195*f6dc9357SAndroid Build Coastguard Worker   const bool result = File.ReadPart(data, size, realProcessedSize);
196*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
197*f6dc9357SAndroid Build Coastguard Worker     *processedSize = realProcessedSize;
198*f6dc9357SAndroid Build Coastguard Worker 
199*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_DEVICE_FILE
200*f6dc9357SAndroid Build Coastguard Worker   VirtPos += realProcessedSize;
201*f6dc9357SAndroid Build Coastguard Worker   PhyPos += realProcessedSize;
202*f6dc9357SAndroid Build Coastguard Worker   #endif
203*f6dc9357SAndroid Build Coastguard Worker 
204*f6dc9357SAndroid Build Coastguard Worker   if (result)
205*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker   #else // Z7_FILE_STREAMS_USE_WIN_FILE
208*f6dc9357SAndroid Build Coastguard Worker 
209*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
210*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
211*f6dc9357SAndroid Build Coastguard Worker   const ssize_t res = File.read_part(data, (size_t)size);
212*f6dc9357SAndroid Build Coastguard Worker   if (res != -1)
213*f6dc9357SAndroid Build Coastguard Worker   {
214*f6dc9357SAndroid Build Coastguard Worker     if (processedSize)
215*f6dc9357SAndroid Build Coastguard Worker       *processedSize = (UInt32)res;
216*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
217*f6dc9357SAndroid Build Coastguard Worker   }
218*f6dc9357SAndroid Build Coastguard Worker   #endif // Z7_FILE_STREAMS_USE_WIN_FILE
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker   {
221*f6dc9357SAndroid Build Coastguard Worker     const DWORD error = ::GetLastError();
222*f6dc9357SAndroid Build Coastguard Worker #if 0
223*f6dc9357SAndroid Build Coastguard Worker     if (File.IsStdStream && error == ERROR_BROKEN_PIPE)
224*f6dc9357SAndroid Build Coastguard Worker       return S_OK; // end of stream
225*f6dc9357SAndroid Build Coastguard Worker #endif
226*f6dc9357SAndroid Build Coastguard Worker     if (Callback)
227*f6dc9357SAndroid Build Coastguard Worker       return Callback->InFileStream_On_Error(CallbackRef, error);
228*f6dc9357SAndroid Build Coastguard Worker     if (error == 0)
229*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
230*f6dc9357SAndroid Build Coastguard Worker     return HRESULT_FROM_WIN32(error);
231*f6dc9357SAndroid Build Coastguard Worker   }
232*f6dc9357SAndroid Build Coastguard Worker }
233*f6dc9357SAndroid Build Coastguard Worker 
234*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
Z7_COM7F_IMF(CStdInFileStream::Read (void * data,UInt32 size,UInt32 * processedSize))235*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize))
236*f6dc9357SAndroid Build Coastguard Worker {
237*f6dc9357SAndroid Build Coastguard Worker   size_t s2 = fread(data, 1, size, stdin);
238*f6dc9357SAndroid Build Coastguard Worker   int error = ferror(stdin);
239*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
240*f6dc9357SAndroid Build Coastguard Worker     *processedSize = s2;
241*f6dc9357SAndroid Build Coastguard Worker   if (s2 <= size && error == 0)
242*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
243*f6dc9357SAndroid Build Coastguard Worker   return E_FAIL;
244*f6dc9357SAndroid Build Coastguard Worker }
245*f6dc9357SAndroid Build Coastguard Worker #else
Z7_COM7F_IMF(CStdInFileStream::Read (void * data,UInt32 size,UInt32 * processedSize))246*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize))
247*f6dc9357SAndroid Build Coastguard Worker {
248*f6dc9357SAndroid Build Coastguard Worker   // printf("\nCStdInFileStream::Read size = %d\n", (unsigned)size);
249*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
250*f6dc9357SAndroid Build Coastguard Worker 
251*f6dc9357SAndroid Build Coastguard Worker   DWORD realProcessedSize;
252*f6dc9357SAndroid Build Coastguard Worker   UInt32 sizeTemp = (1 << 20);
253*f6dc9357SAndroid Build Coastguard Worker   if (sizeTemp > size)
254*f6dc9357SAndroid Build Coastguard Worker     sizeTemp = size;
255*f6dc9357SAndroid Build Coastguard Worker   /* in GUI mode : GetStdHandle(STD_INPUT_HANDLE) returns NULL,
256*f6dc9357SAndroid Build Coastguard Worker      and it doesn't set LastError.  */
257*f6dc9357SAndroid Build Coastguard Worker   /*
258*f6dc9357SAndroid Build Coastguard Worker   SetLastError(0);
259*f6dc9357SAndroid Build Coastguard Worker   const HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
260*f6dc9357SAndroid Build Coastguard Worker   if (!h || h == INVALID_HANDLE_VALUE)
261*f6dc9357SAndroid Build Coastguard Worker   {
262*f6dc9357SAndroid Build Coastguard Worker     if (processedSize)
263*f6dc9357SAndroid Build Coastguard Worker       *processedSize = 0;
264*f6dc9357SAndroid Build Coastguard Worker     if (GetLastError() == 0)
265*f6dc9357SAndroid Build Coastguard Worker       SetLastError(ERROR_INVALID_HANDLE);
266*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
267*f6dc9357SAndroid Build Coastguard Worker   }
268*f6dc9357SAndroid Build Coastguard Worker   */
269*f6dc9357SAndroid Build Coastguard Worker   BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);
270*f6dc9357SAndroid Build Coastguard Worker 
271*f6dc9357SAndroid Build Coastguard Worker   /*
272*f6dc9357SAndroid Build Coastguard Worker   printf("\nCInFileStream::Read: size=%d, processed=%8d res=%d 4rror=%3d\n",
273*f6dc9357SAndroid Build Coastguard Worker     (unsigned)size, (int)realProcessedSize,
274*f6dc9357SAndroid Build Coastguard Worker     (int)res, GetLastError());
275*f6dc9357SAndroid Build Coastguard Worker   */
276*f6dc9357SAndroid Build Coastguard Worker 
277*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
278*f6dc9357SAndroid Build Coastguard Worker     *processedSize = realProcessedSize;
279*f6dc9357SAndroid Build Coastguard Worker   if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
280*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
281*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(res != FALSE);
282*f6dc9357SAndroid Build Coastguard Worker 
283*f6dc9357SAndroid Build Coastguard Worker   #else
284*f6dc9357SAndroid Build Coastguard Worker 
285*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
286*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
287*f6dc9357SAndroid Build Coastguard Worker   ssize_t res;
288*f6dc9357SAndroid Build Coastguard Worker   do
289*f6dc9357SAndroid Build Coastguard Worker   {
290*f6dc9357SAndroid Build Coastguard Worker     res = read(0, data, (size_t)size);
291*f6dc9357SAndroid Build Coastguard Worker   }
292*f6dc9357SAndroid Build Coastguard Worker   while (res < 0 && (errno == EINTR));
293*f6dc9357SAndroid Build Coastguard Worker   if (res == -1)
294*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
295*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
296*f6dc9357SAndroid Build Coastguard Worker     *processedSize = (UInt32)res;
297*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
298*f6dc9357SAndroid Build Coastguard Worker 
299*f6dc9357SAndroid Build Coastguard Worker   #endif
300*f6dc9357SAndroid Build Coastguard Worker }
301*f6dc9357SAndroid Build Coastguard Worker 
302*f6dc9357SAndroid Build Coastguard Worker #endif
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker 
305*f6dc9357SAndroid Build Coastguard Worker /*
306*f6dc9357SAndroid Build Coastguard Worker bool CreateStdInStream(CMyComPtr<ISequentialInStream> &str)
307*f6dc9357SAndroid Build Coastguard Worker {
308*f6dc9357SAndroid Build Coastguard Worker #if 0
309*f6dc9357SAndroid Build Coastguard Worker   CInFileStream *inStreamSpec = new CInFileStream;
310*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);;
311*f6dc9357SAndroid Build Coastguard Worker   if (!inStreamSpec->OpenStdIn())
312*f6dc9357SAndroid Build Coastguard Worker     return false;
313*f6dc9357SAndroid Build Coastguard Worker   if (!inStreamSpec->File.IsStdPipeStream)
314*f6dc9357SAndroid Build Coastguard Worker     str = inStreamLoc.Detach();
315*f6dc9357SAndroid Build Coastguard Worker   else
316*f6dc9357SAndroid Build Coastguard Worker #endif
317*f6dc9357SAndroid Build Coastguard Worker   str = new CStdInFileStream;
318*f6dc9357SAndroid Build Coastguard Worker   return true;
319*f6dc9357SAndroid Build Coastguard Worker }
320*f6dc9357SAndroid Build Coastguard Worker */
321*f6dc9357SAndroid Build Coastguard Worker 
322*f6dc9357SAndroid Build Coastguard Worker #if 0
323*f6dc9357SAndroid Build Coastguard Worker bool CInFileStream::OpenStdIn()
324*f6dc9357SAndroid Build Coastguard Worker {
325*f6dc9357SAndroid Build Coastguard Worker   _info_WasLoaded = false;
326*f6dc9357SAndroid Build Coastguard Worker   // Sleep(100);
327*f6dc9357SAndroid Build Coastguard Worker   bool res = File.AttachStdIn();
328*f6dc9357SAndroid Build Coastguard Worker   if (!res)
329*f6dc9357SAndroid Build Coastguard Worker     return false;
330*f6dc9357SAndroid Build Coastguard Worker #if 1
331*f6dc9357SAndroid Build Coastguard Worker   CStreamFileProps props;
332*f6dc9357SAndroid Build Coastguard Worker   if (GetProps2(&props) != S_OK)
333*f6dc9357SAndroid Build Coastguard Worker   {
334*f6dc9357SAndroid Build Coastguard Worker     // we can ignore that error
335*f6dc9357SAndroid Build Coastguard Worker     return false;
336*f6dc9357SAndroid Build Coastguard Worker   }
337*f6dc9357SAndroid Build Coastguard Worker   // we can't use Size, because Size can be set for pipe streams for some value.
338*f6dc9357SAndroid Build Coastguard Worker   // Seek() sees only current chunk in pipe buffer.
339*f6dc9357SAndroid Build Coastguard Worker   // So Seek() can move across only current unread chunk.
340*f6dc9357SAndroid Build Coastguard Worker   // But after reading that chunk. it can't move position back.
341*f6dc9357SAndroid Build Coastguard Worker   // We need safe check that shows that we can use seek (non-pipe mode)
342*f6dc9357SAndroid Build Coastguard Worker   // Is it safe check that shows that pipe mode was used?
343*f6dc9357SAndroid Build Coastguard Worker   File.IsStdPipeStream = (props.VolID == 0);
344*f6dc9357SAndroid Build Coastguard Worker     // && FILETIME_IsZero(props.CTime)
345*f6dc9357SAndroid Build Coastguard Worker     // && FILETIME_IsZero(props.ATime)
346*f6dc9357SAndroid Build Coastguard Worker     // && FILETIME_IsZero(props.MTime);
347*f6dc9357SAndroid Build Coastguard Worker #endif
348*f6dc9357SAndroid Build Coastguard Worker   // printf("\n######## pipe=%d", (unsigned)File.IsStdPipeStream);
349*f6dc9357SAndroid Build Coastguard Worker   return true;
350*f6dc9357SAndroid Build Coastguard Worker }
351*f6dc9357SAndroid Build Coastguard Worker #endif
352*f6dc9357SAndroid Build Coastguard Worker 
353*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::Seek (Int64 offset,UInt32 seekOrigin,UInt64 * newPosition))354*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
355*f6dc9357SAndroid Build Coastguard Worker {
356*f6dc9357SAndroid Build Coastguard Worker   /*
357*f6dc9357SAndroid Build Coastguard Worker   printf("\nCInFileStream::Seek seekOrigin=%d, offset=%8d, VirtPos=%8d\n",
358*f6dc9357SAndroid Build Coastguard Worker       (unsigned)seekOrigin, (int)offset, (int)VirtPos);
359*f6dc9357SAndroid Build Coastguard Worker   */
360*f6dc9357SAndroid Build Coastguard Worker   if (seekOrigin >= 3)
361*f6dc9357SAndroid Build Coastguard Worker     return STG_E_INVALIDFUNCTION;
362*f6dc9357SAndroid Build Coastguard Worker 
363*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
364*f6dc9357SAndroid Build Coastguard Worker 
365*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_DEVICE_FILE
366*f6dc9357SAndroid Build Coastguard Worker   if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END))
367*f6dc9357SAndroid Build Coastguard Worker   {
368*f6dc9357SAndroid Build Coastguard Worker     switch (seekOrigin)
369*f6dc9357SAndroid Build Coastguard Worker     {
370*f6dc9357SAndroid Build Coastguard Worker       case STREAM_SEEK_SET: break;
371*f6dc9357SAndroid Build Coastguard Worker       case STREAM_SEEK_CUR: offset += VirtPos; break;
372*f6dc9357SAndroid Build Coastguard Worker       case STREAM_SEEK_END: offset += File.Size; break;
373*f6dc9357SAndroid Build Coastguard Worker       default: return STG_E_INVALIDFUNCTION;
374*f6dc9357SAndroid Build Coastguard Worker     }
375*f6dc9357SAndroid Build Coastguard Worker     if (offset < 0)
376*f6dc9357SAndroid Build Coastguard Worker       return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
377*f6dc9357SAndroid Build Coastguard Worker     VirtPos = (UInt64)offset;
378*f6dc9357SAndroid Build Coastguard Worker     if (newPosition)
379*f6dc9357SAndroid Build Coastguard Worker       *newPosition = (UInt64)offset;
380*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
381*f6dc9357SAndroid Build Coastguard Worker   }
382*f6dc9357SAndroid Build Coastguard Worker   #endif
383*f6dc9357SAndroid Build Coastguard Worker 
384*f6dc9357SAndroid Build Coastguard Worker   UInt64 realNewPosition = 0;
385*f6dc9357SAndroid Build Coastguard Worker   const bool result = File.Seek(offset, seekOrigin, realNewPosition);
386*f6dc9357SAndroid Build Coastguard Worker   const HRESULT hres = ConvertBoolToHRESULT(result);
387*f6dc9357SAndroid Build Coastguard Worker 
388*f6dc9357SAndroid Build Coastguard Worker   /* 21.07: new File.Seek() in 21.07 already returns correct (realNewPosition)
389*f6dc9357SAndroid Build Coastguard Worker      in case of error. So we don't need additional code below */
390*f6dc9357SAndroid Build Coastguard Worker   // if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); }
391*f6dc9357SAndroid Build Coastguard Worker 
392*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_DEVICE_FILE
393*f6dc9357SAndroid Build Coastguard Worker   PhyPos = VirtPos = realNewPosition;
394*f6dc9357SAndroid Build Coastguard Worker   #endif
395*f6dc9357SAndroid Build Coastguard Worker 
396*f6dc9357SAndroid Build Coastguard Worker   if (newPosition)
397*f6dc9357SAndroid Build Coastguard Worker     *newPosition = realNewPosition;
398*f6dc9357SAndroid Build Coastguard Worker 
399*f6dc9357SAndroid Build Coastguard Worker   return hres;
400*f6dc9357SAndroid Build Coastguard Worker 
401*f6dc9357SAndroid Build Coastguard Worker   #else
402*f6dc9357SAndroid Build Coastguard Worker 
403*f6dc9357SAndroid Build Coastguard Worker   const off_t res = File.seek((off_t)offset, (int)seekOrigin);
404*f6dc9357SAndroid Build Coastguard Worker   if (res == -1)
405*f6dc9357SAndroid Build Coastguard Worker   {
406*f6dc9357SAndroid Build Coastguard Worker     const HRESULT hres = GetLastError_HRESULT();
407*f6dc9357SAndroid Build Coastguard Worker     if (newPosition)
408*f6dc9357SAndroid Build Coastguard Worker       *newPosition = (UInt64)File.seekToCur();
409*f6dc9357SAndroid Build Coastguard Worker     return hres;
410*f6dc9357SAndroid Build Coastguard Worker   }
411*f6dc9357SAndroid Build Coastguard Worker   if (newPosition)
412*f6dc9357SAndroid Build Coastguard Worker     *newPosition = (UInt64)res;
413*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
414*f6dc9357SAndroid Build Coastguard Worker 
415*f6dc9357SAndroid Build Coastguard Worker   #endif
416*f6dc9357SAndroid Build Coastguard Worker }
417*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::GetSize (UInt64 * size))418*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::GetSize(UInt64 *size))
419*f6dc9357SAndroid Build Coastguard Worker {
420*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(File.GetLength(*size));
421*f6dc9357SAndroid Build Coastguard Worker }
422*f6dc9357SAndroid Build Coastguard Worker 
423*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
424*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::GetProps (UInt64 * size,FILETIME * cTime,FILETIME * aTime,FILETIME * mTime,UInt32 * attrib))425*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib))
426*f6dc9357SAndroid Build Coastguard Worker {
427*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
428*f6dc9357SAndroid Build Coastguard Worker   {
429*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReloadProps())
430*f6dc9357SAndroid Build Coastguard Worker   }
431*f6dc9357SAndroid Build Coastguard Worker   const BY_HANDLE_FILE_INFORMATION &info = _info;
432*f6dc9357SAndroid Build Coastguard Worker   /*
433*f6dc9357SAndroid Build Coastguard Worker   BY_HANDLE_FILE_INFORMATION info;
434*f6dc9357SAndroid Build Coastguard Worker   if (!File.GetFileInformation(&info))
435*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
436*f6dc9357SAndroid Build Coastguard Worker   */
437*f6dc9357SAndroid Build Coastguard Worker   {
438*f6dc9357SAndroid Build Coastguard Worker     if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
439*f6dc9357SAndroid Build Coastguard Worker     if (cTime) *cTime = info.ftCreationTime;
440*f6dc9357SAndroid Build Coastguard Worker     if (aTime) *aTime = info.ftLastAccessTime;
441*f6dc9357SAndroid Build Coastguard Worker     if (mTime) *mTime = info.ftLastWriteTime;
442*f6dc9357SAndroid Build Coastguard Worker     if (attrib) *attrib = info.dwFileAttributes;
443*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
444*f6dc9357SAndroid Build Coastguard Worker   }
445*f6dc9357SAndroid Build Coastguard Worker }
446*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::GetProps2 (CStreamFileProps * props))447*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props))
448*f6dc9357SAndroid Build Coastguard Worker {
449*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
450*f6dc9357SAndroid Build Coastguard Worker   {
451*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReloadProps())
452*f6dc9357SAndroid Build Coastguard Worker   }
453*f6dc9357SAndroid Build Coastguard Worker   const BY_HANDLE_FILE_INFORMATION &info = _info;
454*f6dc9357SAndroid Build Coastguard Worker   /*
455*f6dc9357SAndroid Build Coastguard Worker   BY_HANDLE_FILE_INFORMATION info;
456*f6dc9357SAndroid Build Coastguard Worker   if (!File.GetFileInformation(&info))
457*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
458*f6dc9357SAndroid Build Coastguard Worker   */
459*f6dc9357SAndroid Build Coastguard Worker   {
460*f6dc9357SAndroid Build Coastguard Worker     props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
461*f6dc9357SAndroid Build Coastguard Worker     props->VolID = info.dwVolumeSerialNumber;
462*f6dc9357SAndroid Build Coastguard Worker     props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
463*f6dc9357SAndroid Build Coastguard Worker     props->FileID_High = 0;
464*f6dc9357SAndroid Build Coastguard Worker     props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1;
465*f6dc9357SAndroid Build Coastguard Worker     props->Attrib = info.dwFileAttributes;
466*f6dc9357SAndroid Build Coastguard Worker     props->CTime = info.ftCreationTime;
467*f6dc9357SAndroid Build Coastguard Worker     props->ATime = info.ftLastAccessTime;
468*f6dc9357SAndroid Build Coastguard Worker     props->MTime = info.ftLastWriteTime;
469*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
470*f6dc9357SAndroid Build Coastguard Worker   }
471*f6dc9357SAndroid Build Coastguard Worker }
472*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::GetProperty (PROPID propID,PROPVARIANT * value))473*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value))
474*f6dc9357SAndroid Build Coastguard Worker {
475*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
476*f6dc9357SAndroid Build Coastguard Worker   {
477*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReloadProps())
478*f6dc9357SAndroid Build Coastguard Worker   }
479*f6dc9357SAndroid Build Coastguard Worker 
480*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
481*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
482*f6dc9357SAndroid Build Coastguard Worker 
483*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
484*f6dc9357SAndroid Build Coastguard Worker 
485*f6dc9357SAndroid Build Coastguard Worker  #ifdef Z7_DEVICE_FILE
486*f6dc9357SAndroid Build Coastguard Worker   if (File.IsDeviceFile)
487*f6dc9357SAndroid Build Coastguard Worker   {
488*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
489*f6dc9357SAndroid Build Coastguard Worker     {
490*f6dc9357SAndroid Build Coastguard Worker       case kpidSize:
491*f6dc9357SAndroid Build Coastguard Worker         if (File.SizeDefined)
492*f6dc9357SAndroid Build Coastguard Worker           prop = File.Size;
493*f6dc9357SAndroid Build Coastguard Worker         break;
494*f6dc9357SAndroid Build Coastguard Worker       // case kpidAttrib: prop = (UInt32)0; break;
495*f6dc9357SAndroid Build Coastguard Worker       case kpidPosixAttrib:
496*f6dc9357SAndroid Build Coastguard Worker       {
497*f6dc9357SAndroid Build Coastguard Worker         prop = (UInt32)NWindows::NFile::NFind::NAttributes::
498*f6dc9357SAndroid Build Coastguard Worker             Get_PosixMode_From_WinAttrib(0);
499*f6dc9357SAndroid Build Coastguard Worker         /* GNU TAR by default can't extract file with MY_LIN_S_IFBLK attribute
500*f6dc9357SAndroid Build Coastguard Worker            so we don't use MY_LIN_S_IFBLK here */
501*f6dc9357SAndroid Build Coastguard Worker         // prop = (UInt32)(MY_LIN_S_IFBLK | 0600); // for debug
502*f6dc9357SAndroid Build Coastguard Worker         break;
503*f6dc9357SAndroid Build Coastguard Worker       }
504*f6dc9357SAndroid Build Coastguard Worker       /*
505*f6dc9357SAndroid Build Coastguard Worker       case kpidDeviceMajor:
506*f6dc9357SAndroid Build Coastguard Worker         prop = (UInt32)8; // id for SCSI type device (sda)
507*f6dc9357SAndroid Build Coastguard Worker         break;
508*f6dc9357SAndroid Build Coastguard Worker       case kpidDeviceMinor:
509*f6dc9357SAndroid Build Coastguard Worker         prop = (UInt32)0;
510*f6dc9357SAndroid Build Coastguard Worker         break;
511*f6dc9357SAndroid Build Coastguard Worker       */
512*f6dc9357SAndroid Build Coastguard Worker     }
513*f6dc9357SAndroid Build Coastguard Worker   }
514*f6dc9357SAndroid Build Coastguard Worker   else
515*f6dc9357SAndroid Build Coastguard Worker  #endif
516*f6dc9357SAndroid Build Coastguard Worker   {
517*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
518*f6dc9357SAndroid Build Coastguard Worker     {
519*f6dc9357SAndroid Build Coastguard Worker       case kpidSize:
520*f6dc9357SAndroid Build Coastguard Worker       {
521*f6dc9357SAndroid Build Coastguard Worker         const UInt64 size = (((UInt64)_info.nFileSizeHigh) << 32) + _info.nFileSizeLow;
522*f6dc9357SAndroid Build Coastguard Worker         prop = size;
523*f6dc9357SAndroid Build Coastguard Worker         break;
524*f6dc9357SAndroid Build Coastguard Worker       }
525*f6dc9357SAndroid Build Coastguard Worker       case kpidAttrib:  prop = (UInt32)_info.dwFileAttributes; break;
526*f6dc9357SAndroid Build Coastguard Worker       case kpidCTime:  PropVariant_SetFrom_FiTime(prop, _info.ftCreationTime); break;
527*f6dc9357SAndroid Build Coastguard Worker       case kpidATime:  PropVariant_SetFrom_FiTime(prop, _info.ftLastAccessTime); break;
528*f6dc9357SAndroid Build Coastguard Worker       case kpidMTime:  PropVariant_SetFrom_FiTime(prop, _info.ftLastWriteTime); break;
529*f6dc9357SAndroid Build Coastguard Worker       case kpidPosixAttrib:
530*f6dc9357SAndroid Build Coastguard Worker         prop = (UInt32)NWindows::NFile::NFind::NAttributes::
531*f6dc9357SAndroid Build Coastguard Worker             Get_PosixMode_From_WinAttrib(_info.dwFileAttributes);
532*f6dc9357SAndroid Build Coastguard Worker             // | (UInt32)(1 << 21); // for debug
533*f6dc9357SAndroid Build Coastguard Worker         break;
534*f6dc9357SAndroid Build Coastguard Worker     }
535*f6dc9357SAndroid Build Coastguard Worker   }
536*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
537*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
538*f6dc9357SAndroid Build Coastguard Worker }
539*f6dc9357SAndroid Build Coastguard Worker 
540*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::ReloadProps ())541*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::ReloadProps())
542*f6dc9357SAndroid Build Coastguard Worker {
543*f6dc9357SAndroid Build Coastguard Worker  #ifdef Z7_DEVICE_FILE
544*f6dc9357SAndroid Build Coastguard Worker   if (File.IsDeviceFile)
545*f6dc9357SAndroid Build Coastguard Worker   {
546*f6dc9357SAndroid Build Coastguard Worker     memset(&_info, 0, sizeof(_info));
547*f6dc9357SAndroid Build Coastguard Worker     if (File.SizeDefined)
548*f6dc9357SAndroid Build Coastguard Worker     {
549*f6dc9357SAndroid Build Coastguard Worker       _info.nFileSizeHigh = (DWORD)(File.Size >> 32);
550*f6dc9357SAndroid Build Coastguard Worker       _info.nFileSizeLow = (DWORD)(File.Size);
551*f6dc9357SAndroid Build Coastguard Worker     }
552*f6dc9357SAndroid Build Coastguard Worker     _info.nNumberOfLinks = 1;
553*f6dc9357SAndroid Build Coastguard Worker     _info_WasLoaded = true;
554*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
555*f6dc9357SAndroid Build Coastguard Worker   }
556*f6dc9357SAndroid Build Coastguard Worker  #endif
557*f6dc9357SAndroid Build Coastguard Worker   _info_WasLoaded = File.GetFileInformation(&_info);
558*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
559*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
560*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
561*f6dc9357SAndroid Build Coastguard Worker #if 0
562*f6dc9357SAndroid Build Coastguard Worker   printf(
563*f6dc9357SAndroid Build Coastguard Worker     "\ndwFileAttributes = %8x"
564*f6dc9357SAndroid Build Coastguard Worker     "\nftCreationTime   = %8x"
565*f6dc9357SAndroid Build Coastguard Worker     "\nftLastAccessTime = %8x"
566*f6dc9357SAndroid Build Coastguard Worker     "\nftLastWriteTime  = %8x"
567*f6dc9357SAndroid Build Coastguard Worker     "\ndwVolumeSerialNumber  = %8x"
568*f6dc9357SAndroid Build Coastguard Worker     "\nnFileSizeHigh  = %8x"
569*f6dc9357SAndroid Build Coastguard Worker     "\nnFileSizeLow   = %8x"
570*f6dc9357SAndroid Build Coastguard Worker     "\nnNumberOfLinks  = %8x"
571*f6dc9357SAndroid Build Coastguard Worker     "\nnFileIndexHigh  = %8x"
572*f6dc9357SAndroid Build Coastguard Worker     "\nnFileIndexLow   = %8x \n",
573*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.dwFileAttributes,
574*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.ftCreationTime.dwHighDateTime,
575*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.ftLastAccessTime.dwHighDateTime,
576*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.ftLastWriteTime.dwHighDateTime,
577*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.dwVolumeSerialNumber,
578*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.nFileSizeHigh,
579*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.nFileSizeLow,
580*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.nNumberOfLinks,
581*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.nFileIndexHigh,
582*f6dc9357SAndroid Build Coastguard Worker       (unsigned)_info.nFileIndexLow);
583*f6dc9357SAndroid Build Coastguard Worker #endif
584*f6dc9357SAndroid Build Coastguard Worker #endif
585*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
586*f6dc9357SAndroid Build Coastguard Worker }
587*f6dc9357SAndroid Build Coastguard Worker 
588*f6dc9357SAndroid Build Coastguard Worker 
589*f6dc9357SAndroid Build Coastguard Worker #elif !defined(_WIN32)
590*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::GetProps (UInt64 * size,FILETIME * cTime,FILETIME * aTime,FILETIME * mTime,UInt32 * attrib))591*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib))
592*f6dc9357SAndroid Build Coastguard Worker {
593*f6dc9357SAndroid Build Coastguard Worker   // printf("\nCInFileStream::GetProps VirtPos = %8d\n", (int)VirtPos);
594*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
595*f6dc9357SAndroid Build Coastguard Worker   {
596*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReloadProps())
597*f6dc9357SAndroid Build Coastguard Worker   }
598*f6dc9357SAndroid Build Coastguard Worker   const struct stat &st = _info;
599*f6dc9357SAndroid Build Coastguard Worker   /*
600*f6dc9357SAndroid Build Coastguard Worker   struct stat st;
601*f6dc9357SAndroid Build Coastguard Worker   if (File.my_fstat(&st) != 0)
602*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
603*f6dc9357SAndroid Build Coastguard Worker   */
604*f6dc9357SAndroid Build Coastguard Worker 
605*f6dc9357SAndroid Build Coastguard Worker   if (size) *size = (UInt64)st.st_size;
606*f6dc9357SAndroid Build Coastguard Worker   if (cTime) FiTime_To_FILETIME (ST_CTIME(st), *cTime);
607*f6dc9357SAndroid Build Coastguard Worker   if (aTime) FiTime_To_FILETIME (ST_ATIME(st), *aTime);
608*f6dc9357SAndroid Build Coastguard Worker   if (mTime) FiTime_To_FILETIME (ST_MTIME(st), *mTime);
609*f6dc9357SAndroid Build Coastguard Worker   if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
610*f6dc9357SAndroid Build Coastguard Worker 
611*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
612*f6dc9357SAndroid Build Coastguard Worker }
613*f6dc9357SAndroid Build Coastguard Worker 
614*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
615*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::GetProps2 (CStreamFileProps * props))616*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props))
617*f6dc9357SAndroid Build Coastguard Worker {
618*f6dc9357SAndroid Build Coastguard Worker   // printf("\nCInFileStream::GetProps2 VirtPos = %8d\n", (int)VirtPos);
619*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
620*f6dc9357SAndroid Build Coastguard Worker   {
621*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReloadProps())
622*f6dc9357SAndroid Build Coastguard Worker   }
623*f6dc9357SAndroid Build Coastguard Worker   const struct stat &st = _info;
624*f6dc9357SAndroid Build Coastguard Worker   /*
625*f6dc9357SAndroid Build Coastguard Worker   struct stat st;
626*f6dc9357SAndroid Build Coastguard Worker   if (File.my_fstat(&st) != 0)
627*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
628*f6dc9357SAndroid Build Coastguard Worker   */
629*f6dc9357SAndroid Build Coastguard Worker 
630*f6dc9357SAndroid Build Coastguard Worker   props->Size = (UInt64)st.st_size;
631*f6dc9357SAndroid Build Coastguard Worker   /*
632*f6dc9357SAndroid Build Coastguard Worker     dev_t stat::st_dev:
633*f6dc9357SAndroid Build Coastguard Worker        GCC:Linux  long unsigned int :  __dev_t
634*f6dc9357SAndroid Build Coastguard Worker        Mac:       int
635*f6dc9357SAndroid Build Coastguard Worker   */
636*f6dc9357SAndroid Build Coastguard Worker   props->VolID = (UInt64)(Int64)st.st_dev;
637*f6dc9357SAndroid Build Coastguard Worker   props->FileID_Low = st.st_ino;
638*f6dc9357SAndroid Build Coastguard Worker   props->FileID_High = 0;
639*f6dc9357SAndroid Build Coastguard Worker   props->NumLinks = (UInt32)st.st_nlink; // we reduce to UInt32 from (nlink_t) that is (unsigned long)
640*f6dc9357SAndroid Build Coastguard Worker   props->Attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
641*f6dc9357SAndroid Build Coastguard Worker 
642*f6dc9357SAndroid Build Coastguard Worker   FiTime_To_FILETIME (ST_CTIME(st), props->CTime);
643*f6dc9357SAndroid Build Coastguard Worker   FiTime_To_FILETIME (ST_ATIME(st), props->ATime);
644*f6dc9357SAndroid Build Coastguard Worker   FiTime_To_FILETIME (ST_MTIME(st), props->MTime);
645*f6dc9357SAndroid Build Coastguard Worker 
646*f6dc9357SAndroid Build Coastguard Worker   /*
647*f6dc9357SAndroid Build Coastguard Worker   printf("\nGetProps2() NumLinks=%d = st_dev=%d st_ino = %d\n"
648*f6dc9357SAndroid Build Coastguard Worker       , (unsigned)(props->NumLinks)
649*f6dc9357SAndroid Build Coastguard Worker       , (unsigned)(st.st_dev)
650*f6dc9357SAndroid Build Coastguard Worker       , (unsigned)(st.st_ino)
651*f6dc9357SAndroid Build Coastguard Worker       );
652*f6dc9357SAndroid Build Coastguard Worker   */
653*f6dc9357SAndroid Build Coastguard Worker 
654*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
655*f6dc9357SAndroid Build Coastguard Worker }
656*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::GetProperty (PROPID propID,PROPVARIANT * value))657*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value))
658*f6dc9357SAndroid Build Coastguard Worker {
659*f6dc9357SAndroid Build Coastguard Worker   // printf("\nCInFileStream::GetProperty VirtPos = %8d propID = %3d\n", (int)VirtPos, propID);
660*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
661*f6dc9357SAndroid Build Coastguard Worker   {
662*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReloadProps())
663*f6dc9357SAndroid Build Coastguard Worker   }
664*f6dc9357SAndroid Build Coastguard Worker 
665*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
666*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
667*f6dc9357SAndroid Build Coastguard Worker 
668*f6dc9357SAndroid Build Coastguard Worker   const struct stat &st = _info;
669*f6dc9357SAndroid Build Coastguard Worker 
670*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
671*f6dc9357SAndroid Build Coastguard Worker   {
672*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
673*f6dc9357SAndroid Build Coastguard Worker     {
674*f6dc9357SAndroid Build Coastguard Worker       case kpidSize: prop = (UInt64)st.st_size; break;
675*f6dc9357SAndroid Build Coastguard Worker       case kpidAttrib:
676*f6dc9357SAndroid Build Coastguard Worker         prop = (UInt32)NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
677*f6dc9357SAndroid Build Coastguard Worker         break;
678*f6dc9357SAndroid Build Coastguard Worker       case kpidCTime:  PropVariant_SetFrom_FiTime(prop, ST_CTIME(st)); break;
679*f6dc9357SAndroid Build Coastguard Worker       case kpidATime:  PropVariant_SetFrom_FiTime(prop, ST_ATIME(st)); break;
680*f6dc9357SAndroid Build Coastguard Worker       case kpidMTime:  PropVariant_SetFrom_FiTime(prop, ST_MTIME(st)); break;
681*f6dc9357SAndroid Build Coastguard Worker       case kpidPosixAttrib: prop = (UInt32)st.st_mode; break;
682*f6dc9357SAndroid Build Coastguard Worker 
683*f6dc9357SAndroid Build Coastguard Worker         #if defined(__APPLE__)
684*f6dc9357SAndroid Build Coastguard Worker         #pragma GCC diagnostic push
685*f6dc9357SAndroid Build Coastguard Worker         #pragma GCC diagnostic ignored "-Wsign-conversion"
686*f6dc9357SAndroid Build Coastguard Worker         #endif
687*f6dc9357SAndroid Build Coastguard Worker 
688*f6dc9357SAndroid Build Coastguard Worker       case kpidDeviceMajor:
689*f6dc9357SAndroid Build Coastguard Worker       {
690*f6dc9357SAndroid Build Coastguard Worker         // printf("\nst.st_rdev = %d\n", st.st_rdev);
691*f6dc9357SAndroid Build Coastguard Worker         if (S_ISCHR(st.st_mode) ||
692*f6dc9357SAndroid Build Coastguard Worker             S_ISBLK(st.st_mode))
693*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)(major(st.st_rdev)); //  + 1000);
694*f6dc9357SAndroid Build Coastguard Worker         // prop = (UInt32)12345678; // for debug
695*f6dc9357SAndroid Build Coastguard Worker         break;
696*f6dc9357SAndroid Build Coastguard Worker       }
697*f6dc9357SAndroid Build Coastguard Worker 
698*f6dc9357SAndroid Build Coastguard Worker       case kpidDeviceMinor:
699*f6dc9357SAndroid Build Coastguard Worker         if (S_ISCHR(st.st_mode) ||
700*f6dc9357SAndroid Build Coastguard Worker             S_ISBLK(st.st_mode))
701*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)(minor(st.st_rdev)); // + 100);
702*f6dc9357SAndroid Build Coastguard Worker         // prop = (UInt32)(st.st_rdev); // for debug
703*f6dc9357SAndroid Build Coastguard Worker         // printf("\nst.st_rdev = %d\n", st.st_rdev);
704*f6dc9357SAndroid Build Coastguard Worker         // prop = (UInt32)123456789; // for debug
705*f6dc9357SAndroid Build Coastguard Worker         break;
706*f6dc9357SAndroid Build Coastguard Worker 
707*f6dc9357SAndroid Build Coastguard Worker         #if defined(__APPLE__)
708*f6dc9357SAndroid Build Coastguard Worker         #pragma GCC diagnostic pop
709*f6dc9357SAndroid Build Coastguard Worker         #endif
710*f6dc9357SAndroid Build Coastguard Worker 
711*f6dc9357SAndroid Build Coastguard Worker       /*
712*f6dc9357SAndroid Build Coastguard Worker       case kpidDevice:
713*f6dc9357SAndroid Build Coastguard Worker         if (S_ISCHR(st.st_mode) ||
714*f6dc9357SAndroid Build Coastguard Worker             S_ISBLK(st.st_mode))
715*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt64)(st.st_rdev);
716*f6dc9357SAndroid Build Coastguard Worker         break;
717*f6dc9357SAndroid Build Coastguard Worker       */
718*f6dc9357SAndroid Build Coastguard Worker 
719*f6dc9357SAndroid Build Coastguard Worker       case kpidUserId:
720*f6dc9357SAndroid Build Coastguard Worker       {
721*f6dc9357SAndroid Build Coastguard Worker         if (StoreOwnerId)
722*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)st.st_uid;
723*f6dc9357SAndroid Build Coastguard Worker         break;
724*f6dc9357SAndroid Build Coastguard Worker       }
725*f6dc9357SAndroid Build Coastguard Worker       case kpidGroupId:
726*f6dc9357SAndroid Build Coastguard Worker       {
727*f6dc9357SAndroid Build Coastguard Worker         if (StoreOwnerId)
728*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)st.st_gid;
729*f6dc9357SAndroid Build Coastguard Worker         break;
730*f6dc9357SAndroid Build Coastguard Worker       }
731*f6dc9357SAndroid Build Coastguard Worker       case kpidUser:
732*f6dc9357SAndroid Build Coastguard Worker       {
733*f6dc9357SAndroid Build Coastguard Worker         if (StoreOwnerName)
734*f6dc9357SAndroid Build Coastguard Worker         {
735*f6dc9357SAndroid Build Coastguard Worker           const uid_t uid = st.st_uid;
736*f6dc9357SAndroid Build Coastguard Worker           {
737*f6dc9357SAndroid Build Coastguard Worker             if (!OwnerName.IsEmpty() && _uid == uid)
738*f6dc9357SAndroid Build Coastguard Worker               prop = OwnerName;
739*f6dc9357SAndroid Build Coastguard Worker             else
740*f6dc9357SAndroid Build Coastguard Worker             {
741*f6dc9357SAndroid Build Coastguard Worker               const passwd *pw = getpwuid(uid);
742*f6dc9357SAndroid Build Coastguard Worker               if (pw)
743*f6dc9357SAndroid Build Coastguard Worker               {
744*f6dc9357SAndroid Build Coastguard Worker                 // we can use utf-8 here.
745*f6dc9357SAndroid Build Coastguard Worker                 // prop = pw->pw_name;
746*f6dc9357SAndroid Build Coastguard Worker               }
747*f6dc9357SAndroid Build Coastguard Worker             }
748*f6dc9357SAndroid Build Coastguard Worker           }
749*f6dc9357SAndroid Build Coastguard Worker         }
750*f6dc9357SAndroid Build Coastguard Worker         break;
751*f6dc9357SAndroid Build Coastguard Worker       }
752*f6dc9357SAndroid Build Coastguard Worker       case kpidGroup:
753*f6dc9357SAndroid Build Coastguard Worker       {
754*f6dc9357SAndroid Build Coastguard Worker         if (StoreOwnerName)
755*f6dc9357SAndroid Build Coastguard Worker         {
756*f6dc9357SAndroid Build Coastguard Worker           const uid_t gid = st.st_gid;
757*f6dc9357SAndroid Build Coastguard Worker           {
758*f6dc9357SAndroid Build Coastguard Worker             if (!OwnerGroup.IsEmpty() && _gid == gid)
759*f6dc9357SAndroid Build Coastguard Worker               prop = OwnerGroup;
760*f6dc9357SAndroid Build Coastguard Worker             else
761*f6dc9357SAndroid Build Coastguard Worker             {
762*f6dc9357SAndroid Build Coastguard Worker               const group *gr = getgrgid(gid);
763*f6dc9357SAndroid Build Coastguard Worker               if (gr)
764*f6dc9357SAndroid Build Coastguard Worker               {
765*f6dc9357SAndroid Build Coastguard Worker                 // we can use utf-8 here.
766*f6dc9357SAndroid Build Coastguard Worker                 // prop = gr->gr_name;
767*f6dc9357SAndroid Build Coastguard Worker               }
768*f6dc9357SAndroid Build Coastguard Worker             }
769*f6dc9357SAndroid Build Coastguard Worker           }
770*f6dc9357SAndroid Build Coastguard Worker         }
771*f6dc9357SAndroid Build Coastguard Worker         break;
772*f6dc9357SAndroid Build Coastguard Worker       }
773*f6dc9357SAndroid Build Coastguard Worker       default: break;
774*f6dc9357SAndroid Build Coastguard Worker     }
775*f6dc9357SAndroid Build Coastguard Worker   }
776*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
777*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
778*f6dc9357SAndroid Build Coastguard Worker }
779*f6dc9357SAndroid Build Coastguard Worker 
780*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CInFileStream::ReloadProps ())781*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStream::ReloadProps())
782*f6dc9357SAndroid Build Coastguard Worker {
783*f6dc9357SAndroid Build Coastguard Worker   _info_WasLoaded = (File.my_fstat(&_info) == 0);
784*f6dc9357SAndroid Build Coastguard Worker   if (!_info_WasLoaded)
785*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
786*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
787*f6dc9357SAndroid Build Coastguard Worker }
788*f6dc9357SAndroid Build Coastguard Worker 
789*f6dc9357SAndroid Build Coastguard Worker #endif
790*f6dc9357SAndroid Build Coastguard Worker 
791*f6dc9357SAndroid Build Coastguard Worker 
792*f6dc9357SAndroid Build Coastguard Worker 
793*f6dc9357SAndroid Build Coastguard Worker 
794*f6dc9357SAndroid Build Coastguard Worker //////////////////////////
795*f6dc9357SAndroid Build Coastguard Worker // COutFileStream
796*f6dc9357SAndroid Build Coastguard Worker 
Close()797*f6dc9357SAndroid Build Coastguard Worker HRESULT COutFileStream::Close()
798*f6dc9357SAndroid Build Coastguard Worker {
799*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(File.Close());
800*f6dc9357SAndroid Build Coastguard Worker }
801*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(COutFileStream::Write (const void * data,UInt32 size,UInt32 * processedSize))802*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
803*f6dc9357SAndroid Build Coastguard Worker {
804*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
805*f6dc9357SAndroid Build Coastguard Worker 
806*f6dc9357SAndroid Build Coastguard Worker   UInt32 realProcessedSize;
807*f6dc9357SAndroid Build Coastguard Worker   const bool result = File.Write(data, size, realProcessedSize);
808*f6dc9357SAndroid Build Coastguard Worker   ProcessedSize += realProcessedSize;
809*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
810*f6dc9357SAndroid Build Coastguard Worker     *processedSize = realProcessedSize;
811*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(result);
812*f6dc9357SAndroid Build Coastguard Worker 
813*f6dc9357SAndroid Build Coastguard Worker   #else
814*f6dc9357SAndroid Build Coastguard Worker 
815*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
816*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
817*f6dc9357SAndroid Build Coastguard Worker   size_t realProcessedSize;
818*f6dc9357SAndroid Build Coastguard Worker   const ssize_t res = File.write_full(data, (size_t)size, realProcessedSize);
819*f6dc9357SAndroid Build Coastguard Worker   ProcessedSize += realProcessedSize;
820*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
821*f6dc9357SAndroid Build Coastguard Worker     *processedSize = (UInt32)realProcessedSize;
822*f6dc9357SAndroid Build Coastguard Worker   if (res == -1)
823*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
824*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
825*f6dc9357SAndroid Build Coastguard Worker 
826*f6dc9357SAndroid Build Coastguard Worker   #endif
827*f6dc9357SAndroid Build Coastguard Worker }
828*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(COutFileStream::Seek (Int64 offset,UInt32 seekOrigin,UInt64 * newPosition))829*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
830*f6dc9357SAndroid Build Coastguard Worker {
831*f6dc9357SAndroid Build Coastguard Worker   if (seekOrigin >= 3)
832*f6dc9357SAndroid Build Coastguard Worker     return STG_E_INVALIDFUNCTION;
833*f6dc9357SAndroid Build Coastguard Worker 
834*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
835*f6dc9357SAndroid Build Coastguard Worker 
836*f6dc9357SAndroid Build Coastguard Worker   UInt64 realNewPosition = 0;
837*f6dc9357SAndroid Build Coastguard Worker   const bool result = File.Seek(offset, seekOrigin, realNewPosition);
838*f6dc9357SAndroid Build Coastguard Worker   if (newPosition)
839*f6dc9357SAndroid Build Coastguard Worker     *newPosition = realNewPosition;
840*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(result);
841*f6dc9357SAndroid Build Coastguard Worker 
842*f6dc9357SAndroid Build Coastguard Worker   #else
843*f6dc9357SAndroid Build Coastguard Worker 
844*f6dc9357SAndroid Build Coastguard Worker   const off_t res = File.seek((off_t)offset, (int)seekOrigin);
845*f6dc9357SAndroid Build Coastguard Worker   if (res == -1)
846*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
847*f6dc9357SAndroid Build Coastguard Worker   if (newPosition)
848*f6dc9357SAndroid Build Coastguard Worker     *newPosition = (UInt64)res;
849*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
850*f6dc9357SAndroid Build Coastguard Worker 
851*f6dc9357SAndroid Build Coastguard Worker   #endif
852*f6dc9357SAndroid Build Coastguard Worker }
853*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(COutFileStream::SetSize (UInt64 newSize))854*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COutFileStream::SetSize(UInt64 newSize))
855*f6dc9357SAndroid Build Coastguard Worker {
856*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize));
857*f6dc9357SAndroid Build Coastguard Worker }
858*f6dc9357SAndroid Build Coastguard Worker 
GetSize(UInt64 * size)859*f6dc9357SAndroid Build Coastguard Worker HRESULT COutFileStream::GetSize(UInt64 *size)
860*f6dc9357SAndroid Build Coastguard Worker {
861*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(File.GetLength(*size));
862*f6dc9357SAndroid Build Coastguard Worker }
863*f6dc9357SAndroid Build Coastguard Worker 
864*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
865*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CStdOutFileStream::Write (const void * data,UInt32 size,UInt32 * processedSize))866*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
867*f6dc9357SAndroid Build Coastguard Worker {
868*f6dc9357SAndroid Build Coastguard Worker   size_t s2 = fwrite(data, 1, size, stdout);
869*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
870*f6dc9357SAndroid Build Coastguard Worker     *processedSize = s2;
871*f6dc9357SAndroid Build Coastguard Worker   return (s2 == size) ? S_OK : E_FAIL;
872*f6dc9357SAndroid Build Coastguard Worker }
873*f6dc9357SAndroid Build Coastguard Worker 
874*f6dc9357SAndroid Build Coastguard Worker #else
875*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CStdOutFileStream::Write (const void * data,UInt32 size,UInt32 * processedSize))876*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
877*f6dc9357SAndroid Build Coastguard Worker {
878*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
879*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
880*f6dc9357SAndroid Build Coastguard Worker 
881*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
882*f6dc9357SAndroid Build Coastguard Worker 
883*f6dc9357SAndroid Build Coastguard Worker   UInt32 realProcessedSize;
884*f6dc9357SAndroid Build Coastguard Worker   BOOL res = TRUE;
885*f6dc9357SAndroid Build Coastguard Worker   if (size > 0)
886*f6dc9357SAndroid Build Coastguard Worker   {
887*f6dc9357SAndroid Build Coastguard Worker     // Seems that Windows doesn't like big amounts writing to stdout.
888*f6dc9357SAndroid Build Coastguard Worker     // So we limit portions by 32KB.
889*f6dc9357SAndroid Build Coastguard Worker     UInt32 sizeTemp = (1 << 15);
890*f6dc9357SAndroid Build Coastguard Worker     if (sizeTemp > size)
891*f6dc9357SAndroid Build Coastguard Worker       sizeTemp = size;
892*f6dc9357SAndroid Build Coastguard Worker     res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
893*f6dc9357SAndroid Build Coastguard Worker         data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
894*f6dc9357SAndroid Build Coastguard Worker     _size += realProcessedSize;
895*f6dc9357SAndroid Build Coastguard Worker     size -= realProcessedSize;
896*f6dc9357SAndroid Build Coastguard Worker     data = (const void *)((const Byte *)data + realProcessedSize);
897*f6dc9357SAndroid Build Coastguard Worker     if (processedSize)
898*f6dc9357SAndroid Build Coastguard Worker       *processedSize += realProcessedSize;
899*f6dc9357SAndroid Build Coastguard Worker   }
900*f6dc9357SAndroid Build Coastguard Worker   return ConvertBoolToHRESULT(res != FALSE);
901*f6dc9357SAndroid Build Coastguard Worker 
902*f6dc9357SAndroid Build Coastguard Worker   #else
903*f6dc9357SAndroid Build Coastguard Worker 
904*f6dc9357SAndroid Build Coastguard Worker   ssize_t res;
905*f6dc9357SAndroid Build Coastguard Worker 
906*f6dc9357SAndroid Build Coastguard Worker   do
907*f6dc9357SAndroid Build Coastguard Worker   {
908*f6dc9357SAndroid Build Coastguard Worker     res = write(1, data, (size_t)size);
909*f6dc9357SAndroid Build Coastguard Worker   }
910*f6dc9357SAndroid Build Coastguard Worker   while (res < 0 && (errno == EINTR));
911*f6dc9357SAndroid Build Coastguard Worker 
912*f6dc9357SAndroid Build Coastguard Worker   if (res == -1)
913*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_HRESULT();
914*f6dc9357SAndroid Build Coastguard Worker 
915*f6dc9357SAndroid Build Coastguard Worker   _size += (size_t)res;
916*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
917*f6dc9357SAndroid Build Coastguard Worker     *processedSize = (UInt32)res;
918*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
919*f6dc9357SAndroid Build Coastguard Worker 
920*f6dc9357SAndroid Build Coastguard Worker   #endif
921*f6dc9357SAndroid Build Coastguard Worker }
922*f6dc9357SAndroid Build Coastguard Worker 
923*f6dc9357SAndroid Build Coastguard Worker #endif
924