Merge pull request #4852 from FernetMenta/aefixes
[vuplus_xbmc] / lib / UnrarXLib / filefn.cpp
1 #include "rar.hpp"
2 #ifdef TARGET_POSIX
3 #include "XFileUtils.h"
4 #endif
5
6
7 void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta)
8 {
9 #ifdef _WIN_32
10   bool sm=ftm!=NULL && ftm->IsSet();
11   bool sc=ftc!=NULL && ftc->IsSet();
12   bool sa=ftc!=NULL && fta->IsSet();
13   if (!WinNT())
14     return;
15   HANDLE hFile=CreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
16                           NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
17   if (hFile==INVALID_HANDLE_VALUE)
18     return;
19   FILETIME fm,fc,fa;
20   if (sm)
21     ftm->GetWin32(&fm);
22   if (sc)
23     ftc->GetWin32(&fc);
24   if (sa)
25     fta->GetWin32(&fa);
26   SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
27   CloseHandle(hFile);
28 #endif
29 #if defined(_UNIX) || defined(_EMX)
30   File::SetCloseFileTimeByName(Name,ftm,fta);
31 #endif
32 }
33
34
35 bool IsRemovable(const char *Name)
36 {
37 #if defined(TARGET_POSIX)
38   return false;
39 //#ifdef _WIN_32
40 #elif defined(_WIN_32)
41   char Root[NM];
42   GetPathRoot(Name,Root);
43   int Type=GetDriveType(*Root ? Root:NULL);
44   return(Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM);
45 #elif defined(_EMX)
46   char Drive=toupper(Name[0]);
47   return((Drive=='A' || Drive=='B') && Name[1]==':');
48 #else
49   return(false);
50 #endif
51 }
52
53
54 #ifndef SFX_MODULE
55 Int64 GetFreeDisk(const char *Name)
56 {
57 #if defined(TARGET_POSIX)
58   char Root[NM];
59   GetPathRoot(Name,Root);
60
61   ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
62     uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
63   if ( GetDiskFreeSpaceEx( Root, &uiUserFree, &uiTotalSize, &uiTotalFree ) ) {
64     return(int32to64(uiUserFree.u.HighPart,uiUserFree.u.LowPart));
65   }
66   return 0;
67
68 //#ifdef _WIN_32
69 #elif defined(_WIN_32)
70   char Root[NM];
71   GetPathRoot(Name,Root);
72
73   typedef BOOL (WINAPI *GETDISKFREESPACEEX)(
74     LPCTSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER
75    );
76   static GETDISKFREESPACEEX pGetDiskFreeSpaceEx=NULL;
77
78   if (pGetDiskFreeSpaceEx==NULL)
79   {
80   HMODULE hKernel=GetModuleHandle("kernel32.dll");
81     if (hKernel!=NULL)
82       pGetDiskFreeSpaceEx=(GETDISKFREESPACEEX)GetProcAddress(hKernel,"GetDiskFreeSpaceExA");
83   }
84   if (pGetDiskFreeSpaceEx!=NULL)
85   {
86     GetFilePath(Name,Root);
87     ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
88     uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
89     if (pGetDiskFreeSpaceEx(*Root ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) &&
90         uiUserFree.u.HighPart<=uiTotalFree.u.HighPart)
91       return(int32to64(uiUserFree.u.HighPart,uiUserFree.u.LowPart));
92   }
93
94   DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters;
95   if (!GetDiskFreeSpace(*Root ? Root:NULL,&SectorsPerCluster,&BytesPerSector,&FreeClusters,&TotalClusters))
96     return(1457664);
97   Int64 FreeSize=SectorsPerCluster*BytesPerSector;
98   FreeSize=FreeSize*FreeClusters;
99   return(FreeSize);
100 #elif defined(_BEOS)
101   char Root[NM];
102   GetFilePath(Name,Root);
103   dev_t Dev=dev_for_path(*Root ? Root:".");
104   if (Dev<0)
105     return(1457664);
106   fs_info Info;
107   if (fs_stat_dev(Dev,&Info)!=0)
108     return(1457664);
109   Int64 FreeSize=Info.block_size;
110   FreeSize=FreeSize*Info.free_blocks;
111   return(FreeSize);
112 #elif defined(_UNIX)
113   return(1457664);
114 #elif defined(_EMX)
115   int Drive=(!isalpha(Name[0]) || Name[1]!=':') ? 0:toupper(Name[0])-'A'+1;
116   if (_osmode == OS2_MODE)
117   {
118     FSALLOCATE fsa;
119     if (DosQueryFSInfo(Drive,1,&fsa,sizeof(fsa))!=0)
120       return(1457664);
121     Int64 FreeSize=fsa.cSectorUnit*fsa.cbSector;
122     FreeSize=FreeSize*fsa.cUnitAvail;
123     return(FreeSize);
124   }
125   else
126   {
127     union REGS regs,outregs;
128     memset(&regs,0,sizeof(regs));
129     regs.h.ah=0x36;
130     regs.h.dl=Drive;
131     _int86 (0x21,&regs,&outregs);
132     if (outregs.x.ax==0xffff)
133       return(1457664);
134     Int64 FreeSize=outregs.x.ax*outregs.x.cx;
135     FreeSize=FreeSize*outregs.x.bx;
136     return(FreeSize);
137   }
138 #else
139   #define DISABLEAUTODETECT
140   return(1457664);
141 #endif
142 }
143 #endif
144
145
146 bool FileExist(const char *Name,const wchar *NameW)
147 {
148 #ifdef _WIN_32
149 #if !defined(TARGET_POSIX)
150     if (WinNT() && NameW!=NULL && *NameW!=0)
151       return(GetFileAttributesW(NameW)!=0xffffffff);
152     else
153 #endif
154       return(GetFileAttributes(Name)!=0xffffffff);
155 #elif defined(ENABLE_ACCESS)
156   return(access(Name,0)==0);
157 #else
158   struct FindData FD;
159   return(FindFile::FastFind(Name,NameW,&FD));
160 #endif
161 }
162
163
164 bool WildFileExist(const char *Name,const wchar *NameW)
165 {
166   if (IsWildcard(Name,NameW))
167   {
168     FindFile Find;
169     Find.SetMask(Name);
170     Find.SetMaskW(NameW);
171     struct FindData fd;
172     return(Find.Next(&fd));
173   }
174   return(FileExist(Name,NameW));
175 }
176
177
178 bool IsDir(uint Attr)
179 {
180 #if defined (_WIN_32) || defined(_EMX)
181   return(Attr!=0xffffffff && (Attr & 0x10)!=0);
182 #endif
183 #if defined(_UNIX)
184   return((Attr & 0xF000)==0x4000);
185 #endif
186 }
187
188
189 bool IsUnreadable(uint Attr)
190 {
191 #if defined(_UNIX) && defined(S_ISFIFO) && defined(S_ISSOCK) && defined(S_ISCHR)
192   return(S_ISFIFO(Attr) || S_ISSOCK(Attr) || S_ISCHR(Attr));
193 #endif
194   return(false);
195 }
196
197
198 bool IsLabel(uint Attr)
199 {
200 #if defined (_WIN_32) || defined(_EMX)
201   return((Attr & 8)!=0);
202 #else
203   return(false);
204 #endif
205 }
206
207
208 bool IsLink(uint Attr)
209 {
210 #ifdef _UNIX
211   return((Attr & 0xF000)==0xA000);
212 #endif
213   return(false);
214 }
215
216
217
218
219
220
221 bool IsDeleteAllowed(uint FileAttr)
222 {
223 #if defined(_WIN_32) || defined(_EMX)
224   return((FileAttr & (FA_RDONLY|FA_SYSTEM|FA_HIDDEN))==0);
225 #else
226   return((FileAttr & (S_IRUSR|S_IWUSR))==(S_IRUSR|S_IWUSR));
227 #endif
228 }
229
230
231 void PrepareToDelete(const char *Name,const wchar *NameW)
232 {
233 #if defined(_WIN_32) || defined(_EMX)
234   SetFileAttr(Name,NameW,0);
235 #endif
236 #ifdef _UNIX
237   chmod(Name,S_IRUSR|S_IWUSR|S_IXUSR);
238 #endif
239 }
240
241
242 uint GetFileAttr(const char *Name,const wchar *NameW)
243 {
244 #ifdef _WIN_32
245 #if !defined(TARGET_POSIX)
246     if (WinNT() && NameW!=NULL && *NameW!=0)
247       return(GetFileAttributesW(NameW));
248     else
249 #endif
250       return(GetFileAttributes(Name));
251 #elif defined(_DJGPP)
252   return(_chmod(Name,0));
253 #else
254   struct stat st;
255   if (stat(Name,&st)!=0)
256     return(0);
257 #ifdef _EMX
258   return(st.st_attr);
259 #else
260   return(st.st_mode);
261 #endif
262 #endif
263 }
264
265
266 bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr)
267 {
268   bool success;
269 #ifdef _WIN_32
270 #if !defined(TARGET_POSIX)
271     if (WinNT() && NameW!=NULL && *NameW!=0)
272       success=SetFileAttributesW(NameW,Attr)!=0;
273     else
274 #endif
275       success=SetFileAttributes(Name,Attr)!=0;
276 #elif defined(_DJGPP)
277   success=_chmod(Name,1,Attr)!=-1;
278 #elif defined(_EMX)
279   success=__chmod(Name,1,Attr)!=-1;
280 #elif defined(_UNIX)
281   success=chmod(Name,(mode_t)Attr)==0;
282 #else
283   success=false;
284 #endif
285   return(success);
286 }
287
288
289 void ConvertNameToFull(const char *Src,char *Dest)
290 {
291 #ifdef _WIN_32
292 //#ifndef _WIN_CE
293 #if !defined(_WIN_CE) && !defined(TARGET_POSIX)
294   char FullName[NM],*NamePtr;
295   if (GetFullPathName(Src,sizeof(FullName),FullName,&NamePtr))
296     strcpy(Dest,FullName);
297   else
298 #endif
299     if (Src!=Dest)
300       strcpy(Dest,Src);
301 #else
302   char FullName[NM];
303   if (IsPathDiv(*Src) || IsDiskLetter(Src))
304     strcpy(FullName,Src);
305   else
306   {
307     if (getcwd(FullName,sizeof(FullName)))
308     {
309       AddEndSlash(FullName);
310       strcat(FullName,Src);
311     }
312   }
313   strcpy(Dest,FullName);
314 #endif
315 }
316
317
318 #ifndef SFX_MODULE
319 void ConvertNameToFull(const wchar *Src,wchar *Dest)
320 {
321   if (Src==NULL || *Src==0)
322   {
323     *Dest=0;
324     return;
325   }
326 #ifdef _WIN_32
327 #ifndef _WIN_CE
328   if (WinNT())
329 #endif
330   {
331 //#ifndef _WIN_CE
332 #if !defined(_WIN_CE) && !defined(TARGET_POSIX)
333     wchar FullName[NM],*NamePtr;
334     if (GetFullPathNameW(Src,sizeof(FullName)/sizeof(FullName[0]),FullName,&NamePtr))
335       strcpyw(Dest,FullName);
336     else
337 #endif
338       if (Src!=Dest)
339         strcpyw(Dest,Src);
340   }
341 #ifndef _WIN_CE
342   else
343   {
344     char AnsiName[NM];
345     WideToChar(Src,AnsiName);
346     ConvertNameToFull(AnsiName,AnsiName);
347     CharToWide(AnsiName,Dest);
348   }
349 #endif
350 #else
351   char AnsiName[NM];
352   WideToChar(Src,AnsiName);
353   ConvertNameToFull(AnsiName,AnsiName);
354   CharToWide(AnsiName,Dest);
355 #endif
356 }
357 #endif
358
359
360 #ifndef SFX_MODULE
361 char *MkTemp(char *Name)
362 {
363   int Length=strlen(Name);
364   if (Length<=6)
365     return(NULL);
366   int Random=clock();
367   for (int Attempt=0;;Attempt++)
368   {
369     sprintf(Name+Length-6,"%06u",Random+Attempt);
370     Name[Length-4]='.';
371     if (!FileExist(Name))
372       break;
373     if (Attempt==1000)
374       return(NULL);
375   }
376   return(Name);
377 }
378 #endif
379
380
381
382
383 #ifndef SFX_MODULE
384 uint CalcFileCRC(File *SrcFile,Int64 Size)
385 {
386   SaveFilePos SavePos(*SrcFile);
387   const int BufSize=0x10000;
388   Array<byte> Data(BufSize);
389   Int64 BlockCount=0;
390   uint DataCRC=0xffffffff;
391   int ReadSize;
392
393
394   SrcFile->Seek(0,SEEK_SET);
395   while ((ReadSize=SrcFile->Read(&Data[0],int64to32(Size==INT64ERR ? Int64(BufSize):Min(Int64(BufSize),Size))))!=0)
396   {
397     ++BlockCount;
398     if ((BlockCount & 15)==0)
399     {
400       Wait();
401     }
402     DataCRC=CRC(DataCRC,&Data[0],ReadSize);
403     if (Size!=INT64ERR)
404       Size-=ReadSize;
405   }
406   return(DataCRC^0xffffffff);
407 }
408 #endif
409
410
411 bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW)
412 {
413   return(rename(SrcName,DestName)==0);
414 }
415
416
417 bool DelFile(const char *Name)
418 {
419   return(DelFile(Name,NULL));
420 }
421
422
423 bool DelFile(const char *Name,const wchar *NameW)
424 {
425   return(remove(Name)==0);
426 }
427
428
429 bool DelDir(const char *Name)
430 {
431   return(DelDir(Name,NULL));
432 }
433
434
435 bool DelDir(const char *Name,const wchar *NameW)
436 {
437   return(rmdir(Name)==0);
438 }