home *** CD-ROM | disk | FTP | other *** search
/ ftp.rarlab.com / 2014.05.ftp.rarlab.com.tar / ftp.rarlab.com / rar / unrar_vms_alpha-3.6.5.zip / filefn.cxx < prev    next >
C/C++ Source or Header  |  2006-06-27  |  12KB  |  545 lines

  1. #include "rar.hpp"
  2.  
  3. MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr)
  4. {
  5. #ifdef _WIN_32
  6.   int Success;
  7.   if (WinNT() && NameW!=NULL && *NameW!=0)
  8.     Success=CreateDirectoryW(NameW,NULL);
  9.   else
  10.     Success=CreateDirectory(Name,NULL);
  11.   if (Success)
  12.   {
  13.     SetFileAttr(Name,NameW,Attr);
  14.     return(MKDIR_SUCCESS);
  15.   }
  16.   int ErrCode=GetLastError();
  17.   if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND)
  18.     return(MKDIR_BADPATH);
  19.   return(MKDIR_ERROR);
  20. #endif
  21. #ifdef _EMX
  22. #ifdef _DJGPP
  23.   if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0)
  24. #else
  25.   if (__mkdir(Name)==0)
  26. #endif
  27.   {
  28.     SetFileAttr(Name,NameW,Attr);
  29.     return(MKDIR_SUCCESS);
  30.   }
  31.   return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
  32. #endif
  33. #ifdef _UNIX
  34.   int prevmask=umask(0);
  35.   int ErrCode=Name==NULL ? -1:mkdir(Name,(mode_t)Attr);
  36.   umask(prevmask);
  37.   if (ErrCode==-1)
  38.     return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
  39.   return(MKDIR_SUCCESS);
  40. #endif
  41. }
  42.  
  43.  
  44. void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
  45. {
  46. #ifdef _WIN_32
  47.   uint DirAttr=0;
  48. #else
  49.   uint DirAttr=0777;
  50. #endif
  51. #ifdef UNICODE_SUPPORTED
  52.   bool Wide=PathW!=NULL && *PathW!=0 && UnicodeEnabled();
  53. #else
  54.   bool Wide=false;
  55. #endif
  56.   bool IgnoreAscii=false;
  57.  
  58.   const char *s=Path;
  59.   for (int PosW=0;;PosW++)
  60.   {
  61.     if (s==NULL || s-Path>=NM || *s==0)
  62.       IgnoreAscii=true;
  63.     if (Wide && (PosW>=NM || PathW[PosW]==0) || !Wide && IgnoreAscii)
  64.       break;
  65.     if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER)
  66.     {
  67.       wchar *DirPtrW=NULL,DirNameW[NM];
  68.       if (Wide)
  69.       {
  70.         strncpyw(DirNameW,PathW,PosW);
  71.         DirNameW[PosW]=0;
  72.         DirPtrW=DirNameW;
  73.       }
  74.       char DirName[NM];
  75.       if (IgnoreAscii)
  76.         WideToChar(DirPtrW,DirName);
  77.       else
  78.       {
  79. #ifndef DBCS_SUPPORTED
  80.         if (*s!=CPATHDIVIDER)
  81.           for (const char *n=s;*n!=0 && n-Path<NM;n++)
  82.             if (*n==CPATHDIVIDER)
  83.             {
  84.               s=n;
  85.               break;
  86.             }
  87. #endif
  88.         strncpy(DirName,Path,s-Path);
  89.         DirName[s-Path]=0;
  90.       }
  91.       if (MakeDir(DirName,DirPtrW,DirAttr)==MKDIR_SUCCESS)
  92.       {
  93. #ifndef GUI
  94.         mprintf(St(MCreatDir),DirName);
  95.         mprintf(" %s",St(MOk));
  96. #endif
  97.       }
  98.     }
  99.     if (!IgnoreAscii)
  100.       s=charnext(s);
  101.   }
  102.   if (!SkipLastName && !IsPathDiv(*PointToLastChar(Path)))
  103.     MakeDir(Path,PathW,DirAttr);
  104. }
  105.  
  106.  
  107. void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta)
  108. {
  109. #ifdef _WIN_32
  110.   if (!WinNT())
  111.     return;
  112.  
  113.   bool sm=ftm!=NULL && ftm->IsSet();
  114.   bool sc=ftc!=NULL && ftc->IsSet();
  115.   bool sa=fta!=NULL && fta->IsSet();
  116.  
  117.   unsigned int DirAttr=GetFileAttr(Name);
  118.   bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FA_RDONLY)!=0);
  119.   if (ResetAttr)
  120.     SetFileAttr(Name,NULL,0);
  121.   HANDLE hFile=CreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
  122.                           NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
  123.   if (hFile==INVALID_HANDLE_VALUE)
  124.     return;
  125.   FILETIME fm,fc,fa;
  126.   if (sm)
  127.     ftm->GetWin32(&fm);
  128.   if (sc)
  129.     ftc->GetWin32(&fc);
  130.   if (sa)
  131.     fta->GetWin32(&fa);
  132.   SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
  133.   CloseHandle(hFile);
  134.   if (ResetAttr)
  135.     SetFileAttr(Name,NULL,DirAttr);
  136. #endif
  137. #if defined(_UNIX) || defined(_EMX)
  138.   File::SetCloseFileTimeByName(Name,ftm,fta);
  139. #endif
  140. }
  141.  
  142.  
  143. bool IsRemovable(const char *Name)
  144. {
  145. #ifdef _WIN_32
  146.   char Root[NM];
  147.   GetPathRoot(Name,Root);
  148.   int Type=GetDriveType(*Root ? Root:NULL);
  149.   return(Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM);
  150. #elif defined(_EMX)
  151.   char Drive=toupper(Name[0]);
  152.   return((Drive=='A' || Drive=='B') && Name[1]==':');
  153. #else
  154.   return(false);
  155. #endif
  156. }
  157.  
  158.  
  159. #ifndef SFX_MODULE
  160. Int64 GetFreeDisk(const char *Name)
  161. {
  162. #ifdef _WIN_32
  163.   char Root[NM];
  164.   GetPathRoot(Name,Root);
  165.  
  166.   typedef BOOL (WINAPI *GETDISKFREESPACEEX)(
  167.     LPCTSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER
  168.    );
  169.   static GETDISKFREESPACEEX pGetDiskFreeSpaceEx=NULL;
  170.  
  171.   if (pGetDiskFreeSpaceEx==NULL)
  172.   {
  173.     HMODULE hKernel=GetModuleHandle("kernel32.dll");
  174.     if (hKernel!=NULL)
  175.       pGetDiskFreeSpaceEx=(GETDISKFREESPACEEX)GetProcAddress(hKernel,"GetDiskFreeSpaceExA");
  176.   }
  177.   if (pGetDiskFreeSpaceEx!=NULL)
  178.   {
  179.     GetFilePath(Name,Root);
  180.     ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
  181.     uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
  182.     if (pGetDiskFreeSpaceEx(*Root ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) &&
  183.         uiUserFree.u.HighPart<=uiTotalFree.u.HighPart)
  184.       return(int32to64(uiUserFree.u.HighPart,uiUserFree.u.LowPart));
  185.   }
  186.  
  187.   DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters;
  188.   if (!GetDiskFreeSpace(*Root ? Root:NULL,&SectorsPerCluster,&BytesPerSector,&FreeClusters,&TotalClusters))
  189.     return(1457664);
  190.   Int64 FreeSize=SectorsPerCluster*BytesPerSector;
  191.   FreeSize=FreeSize*FreeClusters;
  192.   return(FreeSize);
  193. #elif defined(_BEOS)
  194.   char Root[NM];
  195.   GetFilePath(Name,Root);
  196.   dev_t Dev=dev_for_path(*Root ? Root:".");
  197.   if (Dev<0)
  198.     return(1457664);
  199.   fs_info Info;
  200.   if (fs_stat_dev(Dev,&Info)!=0)
  201.     return(1457664);
  202.   Int64 FreeSize=Info.block_size;
  203.   FreeSize=FreeSize*Info.free_blocks;
  204.   return(FreeSize);
  205. #elif defined(_UNIX)
  206.   return(1457664);
  207. #elif defined(_EMX)
  208.   int Drive=(!isalpha(Name[0]) || Name[1]!=':') ? 0:toupper(Name[0])-'A'+1;
  209.   if (_osmode == OS2_MODE)
  210.   {
  211.     FSALLOCATE fsa;
  212.     if (DosQueryFSInfo(Drive,1,&fsa,sizeof(fsa))!=0)
  213.       return(1457664);
  214.     Int64 FreeSize=fsa.cSectorUnit*fsa.cbSector;
  215.     FreeSize=FreeSize*fsa.cUnitAvail;
  216.     return(FreeSize);
  217.   }
  218.   else
  219.   {
  220.     union REGS regs,outregs;
  221.     memset(®s,0,sizeof(regs));
  222.     regs.h.ah=0x36;
  223.     regs.h.dl=Drive;
  224.     _int86 (0x21,®s,&outregs);
  225.     if (outregs.x.ax==0xffff)
  226.       return(1457664);
  227.     Int64 FreeSize=outregs.x.ax*outregs.x.cx;
  228.     FreeSize=FreeSize*outregs.x.bx;
  229.     return(FreeSize);
  230.   }
  231. #else
  232.   #define DISABLEAUTODETECT
  233.   return(1457664);
  234. #endif
  235. }
  236. #endif
  237.  
  238.  
  239. bool FileExist(const char *Name,const wchar *NameW)
  240. {
  241. #ifdef _WIN_32
  242.     if (WinNT() && NameW!=NULL && *NameW!=0)
  243.       return(GetFileAttributesW(NameW)!=0xffffffff);
  244.     else
  245.       return(GetFileAttributes(Name)!=0xffffffff);
  246. #elif defined(ENABLE_ACCESS)
  247.   return(access(Name,0)==0);
  248. #else
  249.   struct FindData FD;
  250.   return(FindFile::FastFind(Name,NameW,&FD));
  251. #endif
  252. }
  253.  
  254.  
  255. bool WildFileExist(const char *Name,const wchar *NameW)
  256. {
  257.   if (IsWildcard(Name,NameW))
  258.   {
  259.     FindFile Find;
  260.     Find.SetMask(Name);
  261.     Find.SetMaskW(NameW);
  262.     struct FindData fd;
  263.     return(Find.Next(&fd));
  264.   }
  265.   return(FileExist(Name,NameW));
  266. }
  267.  
  268.  
  269. bool IsDir(uint Attr)
  270. {
  271. #if defined (_WIN_32) || defined(_EMX)
  272.   return(Attr!=0xffffffff && (Attr & 0x10)!=0);
  273. #endif
  274. #if defined(_UNIX)
  275.   return((Attr & 0xF000)==0x4000);
  276. #endif
  277. }
  278.  
  279.  
  280. bool IsUnreadable(uint Attr)
  281. {
  282. #if defined(_UNIX) && defined(S_ISFIFO) && defined(S_ISSOCK) && defined(S_ISCHR)
  283.   return(S_ISFIFO(Attr) || S_ISSOCK(Attr) || S_ISCHR(Attr));
  284. #else
  285.  
  286.   return(false);
  287. #endif  
  288. }
  289.  
  290.  
  291. bool IsLabel(uint Attr)
  292. {
  293. #if defined (_WIN_32) || defined(_EMX)
  294.   return((Attr & 8)!=0);
  295. #else
  296.   return(false);
  297. #endif
  298. }
  299.  
  300.  
  301. bool IsLink(uint Attr)
  302. {
  303. #ifdef _UNIX
  304.   return((Attr & 0xF000)==0xA000);
  305. #else
  306.   return(false);
  307. #endif  
  308. }
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315. bool IsDeleteAllowed(uint FileAttr)
  316. {
  317. #if defined(_WIN_32) || defined(_EMX)
  318.   return((FileAttr & (FA_RDONLY|FA_SYSTEM|FA_HIDDEN))==0);
  319. #else
  320.   return((FileAttr & (S_IRUSR|S_IWUSR))==(S_IRUSR|S_IWUSR));
  321. #endif
  322. }
  323.  
  324.  
  325. void PrepareToDelete(const char *Name,const wchar *NameW)
  326. {
  327. #if defined(_WIN_32) || defined(_EMX)
  328.   SetFileAttr(Name,NameW,0);
  329. #endif
  330. #ifdef _UNIX
  331.   chmod(Name,S_IRUSR|S_IWUSR|S_IXUSR);
  332. #endif
  333. }
  334.  
  335.  
  336. uint GetFileAttr(const char *Name,const wchar *NameW)
  337. {
  338. #ifdef _WIN_32
  339.     if (WinNT() && NameW!=NULL && *NameW!=0)
  340.       return(GetFileAttributesW(NameW));
  341.     else
  342.       return(GetFileAttributes(Name));
  343. #elif defined(_DJGPP)
  344.   return(_chmod(Name,0));
  345. #else
  346.   struct stat st;
  347.   if (stat(Name,&st)!=0)
  348.     return(0);
  349. #ifdef _EMX
  350.   return(st.st_attr);
  351. #else
  352.   return(st.st_mode);
  353. #endif
  354. #endif
  355. }
  356.  
  357.  
  358. bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr)
  359. {
  360.   bool Success;
  361. #ifdef _WIN_32
  362.     if (WinNT() && NameW!=NULL && *NameW!=0)
  363.       Success=SetFileAttributesW(NameW,Attr)!=0;
  364.     else
  365.       Success=SetFileAttributes(Name,Attr)!=0;
  366. #elif defined(_DJGPP)
  367.   Success=_chmod(Name,1,Attr)!=-1;
  368. #elif defined(_EMX)
  369.   Success=__chmod(Name,1,Attr)!=-1;
  370. #elif defined(_UNIX)
  371.   Success=chmod(Name,(mode_t)Attr)==0;
  372. #else
  373.   Success=false;
  374. #endif
  375.   return(Success);
  376. }
  377.  
  378.  
  379. void ConvertNameToFull(const char *Src,char *Dest)
  380. {
  381. #ifdef _WIN_32
  382. #ifndef _WIN_CE
  383.   char FullName[NM],*NamePtr;
  384.   if (GetFullPathName(Src,sizeof(FullName),FullName,&NamePtr))
  385.     strcpy(Dest,FullName);
  386.   else
  387. #endif
  388.     if (Src!=Dest)
  389.       strcpy(Dest,Src);
  390. #else
  391.   char FullName[NM];
  392.   if (IsPathDiv(*Src) || IsDiskLetter(Src))
  393.     strcpy(FullName,Src);
  394.   else
  395.   {
  396.     getcwd(FullName,sizeof(FullName));
  397.     AddEndSlash(FullName);
  398.     strcat(FullName,Src);
  399.   }
  400.   strcpy(Dest,FullName);
  401. #endif
  402. }
  403.  
  404.  
  405. #ifndef SFX_MODULE
  406. void ConvertNameToFull(const wchar *Src,wchar *Dest)
  407. {
  408.   if (Src==NULL || *Src==0)
  409.   {
  410.     *Dest=0;
  411.     return;
  412.   }
  413. #ifdef _WIN_32
  414. #ifndef _WIN_CE
  415.   if (WinNT())
  416. #endif
  417.   {
  418. #ifndef _WIN_CE
  419.     wchar FullName[NM],*NamePtr;
  420.     if (GetFullPathNameW(Src,sizeof(FullName)/sizeof(FullName[0]),FullName,&NamePtr))
  421.       strcpyw(Dest,FullName);
  422.     else
  423. #endif
  424.       if (Src!=Dest)
  425.         strcpyw(Dest,Src);
  426.   }
  427. #ifndef _WIN_CE
  428.   else
  429.   {
  430.     char AnsiName[NM];
  431.     WideToChar(Src,AnsiName);
  432.     ConvertNameToFull(AnsiName,AnsiName);
  433.     CharToWide(AnsiName,Dest);
  434.   }
  435. #endif
  436. #else
  437.   char AnsiName[NM];
  438.   WideToChar(Src,AnsiName);
  439.   ConvertNameToFull(AnsiName,AnsiName);
  440.   CharToWide(AnsiName,Dest);
  441. #endif
  442. }
  443. #endif
  444.  
  445.  
  446. #ifndef SFX_MODULE
  447. char *MkTemp(char *Name)
  448. {
  449.   int Length=strlen(Name);
  450.   if (Length<=6)
  451.     return(NULL);
  452.   int Random=clock();
  453.   for (int Attempt=0;;Attempt++)
  454.   {
  455.     sprintf(Name+Length-6,"%06u",Random+Attempt);
  456.     Name[Length-4]='.';
  457.     if (!FileExist(Name))
  458.       break;
  459.     if (Attempt==1000)
  460.       return(NULL);
  461.   }
  462.   return(Name);
  463. }
  464. #endif
  465.  
  466.  
  467.  
  468.  
  469. #ifndef SFX_MODULE
  470. uint CalcFileCRC(File *SrcFile,Int64 Size)
  471. {
  472.   SaveFilePos SavePos(*SrcFile);
  473.   const int BufSize=0x10000;
  474.   Array<byte> Data(BufSize);
  475.   Int64 BlockCount=0;
  476.   uint DataCRC=0xffffffff;
  477.   int ReadSize;
  478.  
  479.  
  480.   SrcFile->Seek(0,SEEK_SET);
  481.   while ((ReadSize=SrcFile->Read(&Data[0],int64to32(Size==INT64ERR ? Int64(BufSize):Min(Int64(BufSize),Size))))!=0)
  482.   {
  483.     ++BlockCount;
  484.     if ((BlockCount & 15)==0)
  485.     {
  486.       Wait();
  487.     }
  488.     DataCRC=CRC(DataCRC,&Data[0],ReadSize);
  489.     if (Size!=INT64ERR)
  490.       Size-=ReadSize;
  491.   }
  492.   return(DataCRC^0xffffffff);
  493. }
  494. #endif
  495.  
  496.  
  497. bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW)
  498. {
  499.   return(rename(SrcName,DestName)==0);
  500. }
  501.  
  502.  
  503. bool DelFile(const char *Name)
  504. {
  505.   return(DelFile(Name,NULL));
  506. }
  507.  
  508.  
  509. bool DelFile(const char *Name,const wchar *NameW)
  510. {
  511.   return(remove(Name)==0);
  512. }
  513.  
  514.  
  515. bool DelDir(const char *Name)
  516. {
  517.   return(DelDir(Name,NULL));
  518. }
  519.  
  520.  
  521. bool DelDir(const char *Name,const wchar *NameW)
  522. {
  523.   return(rmdir(Name)==0);
  524. }
  525.  
  526.  
  527. #if defined(_WIN_32) && !defined(_WIN_CE)
  528. bool SetFileCompression(char *Name,wchar *NameW,bool State)
  529. {
  530.   wchar FileNameW[NM];
  531.   GetWideName(Name,NameW,FileNameW);
  532.   HANDLE hFile=CreateFileW(FileNameW,FILE_READ_DATA|FILE_WRITE_DATA,
  533.                  FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
  534.                  FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
  535.   if (hFile==INVALID_HANDLE_VALUE)
  536.     return(false);
  537.   SHORT NewState=State ? COMPRESSION_FORMAT_DEFAULT:COMPRESSION_FORMAT_NONE;
  538.   DWORD Result;
  539.   int RetCode=DeviceIoControl(hFile,FSCTL_SET_COMPRESSION,&NewState,
  540.                               sizeof(NewState),NULL,0,&Result,NULL);
  541.   CloseHandle(hFile);
  542.   return(RetCode!=0);
  543. }
  544. #endif
  545.