/lib/UnrarXLib/filefn.cpp

http://github.com/xbmc/xbmc · C++ · 438 lines · 377 code · 57 blank · 4 comment · 65 complexity · a589f84c24a7e45f3a1d01635dcc9063 MD5 · raw file

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