bool File::Create(const char *Name,const wchar *NameW) { #ifdef _WIN_32 if (WinNT() && NameW!=NULL && *NameW!=0) hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL, CREATE_ALWAYS,0,NULL); else hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL, CREATE_ALWAYS,0,NULL); #else hFile=fopen(Name,CREATEBINARY); #endif NewFile=true; HandleType=FILE_HANDLENORMAL; SkipClose=false; if (NameW!=NULL) strcpyw(FileNameW,NameW); else *FileNameW=0; if (Name!=NULL) strcpy(FileName,Name); else WideToChar(NameW,FileName); AddFileToList(hFile); return(hFile!=BAD_HANDLE); }
void ExtractACLNew(Archive &Arc,char *FileName,wchar *FileNameW) { #if defined(_XBOX) || defined(_LINUX) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) return; #else if (!WinNT()) return; Array<byte> SubData; if (!Arc.ReadSubData(&SubData,NULL)) return; SetPrivileges(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; int SetCode; if (FileNameW!=NULL) SetCode=SetFileSecurityW(FileNameW,si,sd); else SetCode=SetFileSecurity(FileName,si,sd); if (!SetCode) { RarLog(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(WARNING); } #endif }
void ConvertNameToFull(const wchar *Src,wchar *Dest) { if (Src==NULL || *Src==0) { *Dest=0; return; } #ifdef _WIN_32 if (WinNT()) { wchar FullName[NM],*NamePtr; if (GetFullPathNameW(Src,sizeof(FullName)/sizeof(FullName[0]),FullName,&NamePtr)) strcpyw(Dest,FullName); else if (Src!=Dest) strcpyw(Dest,Src); } else { char AnsiName[NM]; WideToChar(Src,AnsiName); ConvertNameToFull(AnsiName,AnsiName); CharToWide(AnsiName,Dest); } #else char AnsiName[NM]; WideToChar(Src,AnsiName); ConvertNameToFull(AnsiName,AnsiName); CharToWide(AnsiName,Dest); #endif }
void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta) { bool sm=ftm!=NULL && ftm->IsSet(); bool sc=ftc!=NULL && ftc->IsSet(); bool sa=ftc!=NULL && fta->IsSet(); #ifdef _WIN_32 if (!WinNT()) return; HANDLE hFile=CreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL); if (hFile==INVALID_HANDLE_VALUE) return; FILETIME fm,fc,fa; if (sm) ftm->GetWin32(&fm); if (sc) ftc->GetWin32(&fc); if (sa) fta->GetWin32(&fa); SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL); CloseHandle(hFile); #endif #if defined(_UNIX) || defined(_EMX) File::SetCloseFileTimeByName(Name,ftm,fta); #endif }
void ExtractACLNew(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; Array<byte> SubData; if (!Arc.ReadSubData(&SubData,(File *) NULL)) return; SetPrivileges(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; int SetCode; if (FileNameW!=NULL) SetCode=SetFileSecurityW(FileNameW,si,sd); else SetCode=SetFileSecurityA(FileName,si,sd); if (!SetCode) { Log(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(WARNING); } }
void ExtractACL(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; SetPrivileges(); if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC) { Log(Arc.FileName,St(MACLBroken),FileName); ErrHandler.SetErrorCode(CRC_ERROR); return; } if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER) { Log(Arc.FileName,St(MACLUnknown),FileName); ErrHandler.SetErrorCode(WARNING); return; } ComprDataIO DataIO; Unpack Unpack(&DataIO); Unpack.Init(); Array<byte> UnpData(Arc.EAHead.UnpSize); DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize); DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize); DataIO.EnableShowProgress(false); DataIO.SetFiles(&Arc,NULL); Unpack.SetDestSize(Arc.EAHead.UnpSize); Unpack.DoUnpack(Arc.EAHead.UnpVer,false); if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC) { Log(Arc.FileName,St(MACLBroken),FileName); ErrHandler.SetErrorCode(CRC_ERROR); return; } SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0]; int SetCode; if (FileNameW!=NULL) SetCode=SetFileSecurityW(FileNameW,si,sd); else SetCode=SetFileSecurityA(FileName,si,sd); if (!SetCode) { Log(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(WARNING); } }
void ExtractStreamsNew(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; wchar NameW[NM]; if (FileNameW!=NULL && *FileNameW!=0) strcpyw(NameW,FileNameW); else CharToWide(FileName,NameW); wchar StreamNameW[NM+2]; if (NameW[0]!=0 && NameW[1]==0) { strcpyw(StreamNameW,L".\\"); strcpyw(StreamNameW+2,NameW); } else strcpyw(StreamNameW,NameW); wchar *DestName=StreamNameW+strlenw(StreamNameW); byte *SrcName=&Arc.SubHead.SubData[0]; int DestSize=Arc.SubHead.SubData.Size()/2; if (strlenw(StreamNameW)+DestSize>=sizeof(StreamNameW)/sizeof(StreamNameW[0])) { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName,St(MStreamBroken),FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } RawToWide(SrcName,DestName,DestSize); DestName[DestSize]=0; FindData fd; bool Found=FindFile::FastFind(FileName,FileNameW,&fd); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY); char StreamName[NM]; WideToChar(StreamNameW,StreamName); File CurFile; if (CurFile.WCreate(StreamName,StreamNameW) && Arc.ReadSubData(NULL,&CurFile)) CurFile.Close(); File HostFile; if (Found && HostFile.Open(FileName,FileNameW,true,true)) SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime, &fd.ftLastWriteTime); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr); }
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr) { #ifdef _WIN_ALL BOOL RetCode; if (WinNT() && NameW!=NULL && *NameW!=0) RetCode=CreateDirectoryW(NameW,NULL); else if (Name!=NULL) RetCode=CreateDirectoryA(Name,NULL); else return(MKDIR_BADPATH); if (RetCode!=0) // Non-zero return code means success for CreateDirectory. { if (SetAttr) SetFileAttr(Name,NameW,Attr); return(MKDIR_SUCCESS); } int ErrCode=GetLastError(); if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND) return(MKDIR_BADPATH); return(MKDIR_ERROR); #else // No Unicode in the rest of function, so Name must be not NULL. if (Name==NULL) return(MKDIR_BADPATH); #endif #ifdef _EMX #ifdef _DJGPP if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0) #else if (__mkdir(Name)==0) #endif { if (SetAttr) SetFileAttr(Name,NameW,Attr); return(MKDIR_SUCCESS); } return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); #endif #ifdef _UNIX mode_t uattr=SetAttr ? (mode_t)Attr:0777; int ErrCode=mkdir(Name,uattr); if (ErrCode==-1) return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); return(MKDIR_SUCCESS); #endif }
bool FileExist(const char *Name,const wchar *NameW) { #ifdef _WIN_ALL if (WinNT() && NameW!=NULL && *NameW!=0) return(GetFileAttributesW(NameW)!=0xffffffff); else return(Name!=NULL && GetFileAttributesA(Name)!=0xffffffff); #elif defined(ENABLE_ACCESS) return(access(Name,0)==0); #else FindData FD; return(FindFile::FastFind(Name,NameW,&FD)); #endif }
bool FileExist(const char *FileName,const wchar *FileNameW) { #ifdef _WIN_32 if (WinNT() && FileNameW!=NULL && *FileNameW!=0) return(GetFileAttributesW(FileNameW)!=0xffffffff); else return(GetFileAttributes(FileName)!=0xffffffff); #elif defined(ENABLE_ACCESS) return(access(FileName,0)==0); #else struct FindData FD; return(FindFile::FastFind(FileName,FileNameW,&FD)); #endif }
bool FileExist(const char *Name,const wchar *NameW) { #ifdef _WIN_32 #if !defined(_XBOX) && !defined(_LINUX) if (WinNT() && NameW!=NULL && *NameW!=0) return(GetFileAttributesW(NameW)!=0xffffffff); else #endif return(GetFileAttributes(Name)!=0xffffffff); #elif defined(ENABLE_ACCESS) return(access(Name,0)==0); #else struct FindData FD; return(FindFile::FastFind(Name,NameW,&FD)); #endif }
void RarTime::SetLocal(RarLocalTime *lt) { #ifdef _WIN_ALL SYSTEMTIME st; st.wYear=lt->Year; st.wMonth=lt->Month; st.wDay=lt->Day; st.wHour=lt->Hour; st.wMinute=lt->Minute; st.wSecond=lt->Second; st.wMilliseconds=0; st.wDayOfWeek=0; FILETIME lft; if (SystemTimeToFileTime(&st,&lft)) { lft.dwLowDateTime+=lt->Reminder; if (lft.dwLowDateTime<lt->Reminder) lft.dwHighDateTime++; FILETIME ft; if (WinNT() < WNT_VISTA) { // TzSpecificLocalTimeToSystemTime based code produces 1 hour error on XP. LocalFileTimeToFileTime(&lft,&ft); } else { // Reverse procedure which we do in GetLocal. SYSTEMTIME st1,st2; FileTimeToSystemTime(&lft,&st2); // st2 might be unequal to st, because we added lt->Reminder to lft. TzSpecificLocalTimeToSystemTime(NULL,&st2,&st1); SystemTimeToFileTime(&st1,&ft); // Correct precision loss (low 4 decimal digits) in FileTimeToSystemTime. FILETIME rft; SystemTimeToFileTime(&st2,&rft); int64 Corrected=INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime)- INT32TO64(rft.dwHighDateTime,rft.dwLowDateTime)+ INT32TO64(ft.dwHighDateTime,ft.dwLowDateTime); ft.dwLowDateTime=(DWORD)Corrected; ft.dwHighDateTime=(DWORD)(Corrected>>32); } *this=ft; }
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr) { bool Success; #ifdef _WIN_32 if (WinNT() && NameW!=NULL && *NameW!=0) Success=SetFileAttributesW(NameW,Attr)!=0; else Success=SetFileAttributes(Name,Attr)!=0; #elif defined(_DJGPP) Success=_chmod(Name,1,Attr)!=-1; #elif defined(_EMX) Success=__chmod(Name,1,Attr)!=-1; #elif defined(_UNIX) Success=chmod(Name,(mode_t)Attr)==0; #else Success=false; #endif return(Success); }
uint GetFileAttr(const char *Name,const wchar *NameW) { #ifdef _WIN_32 if (WinNT() && NameW!=NULL && *NameW!=0) return(GetFileAttributesW(NameW)); else return(GetFileAttributes(Name)); #elif defined(_DJGPP) return(_chmod(Name,0)); #else struct stat st; if (stat(Name,&st)!=0) return(0); #ifdef _EMX return(st.st_attr); #else return(st.st_mode); #endif #endif }
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr) { #ifdef _WIN_32 int Success; #if !defined(_XBOX) && !defined(_LINUX) if (WinNT() && NameW!=NULL && *NameW!=0) Success=CreateDirectoryW(NameW,NULL); else #endif Success=CreateDirectory(Name,NULL); if (Success) { SetFileAttr(Name,NameW,Attr); return(MKDIR_SUCCESS); } int ErrCode=GetLastError(); if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND) return(MKDIR_BADPATH); return(MKDIR_ERROR); #endif #ifdef _EMX #ifdef _DJGPP if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0) #else if (__mkdir(Name)==0) #endif { SetFileAttr(Name,NameW,Attr); return(MKDIR_SUCCESS); } return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); #endif #ifdef _UNIX int prevmask=umask(0); int ErrCode=Name==NULL ? -1:mkdir(Name,(mode_t)Attr); umask(prevmask); if (ErrCode==-1) return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); return(MKDIR_SUCCESS); #endif }
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr) { bool success; #ifdef _WIN_32 #if !defined(_XBOX) && !defined(_LINUX) if (WinNT() && NameW!=NULL && *NameW!=0) success=SetFileAttributesW(NameW,Attr)!=0; else #endif success=SetFileAttributes(Name,Attr)!=0; #elif defined(_DJGPP) success=_chmod(Name,1,Attr)!=-1; #elif defined(_EMX) success=__chmod(Name,1,Attr)!=-1; #elif defined(_UNIX) success=chmod(Name,(mode_t)Attr)==0; #else success=false; #endif return(success); }
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr) { #ifdef _WIN_32 int Success; if (WinNT() && NameW!=NULL && *NameW!=0) Success=CreateDirectoryW(NameW,NULL); else Success=CreateDirectory(Name,NULL); if (Success) { if (SetAttr) SetFileAttr(Name,NameW,Attr); return(MKDIR_SUCCESS); } int ErrCode=GetLastError(); if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND) return(MKDIR_BADPATH); return(MKDIR_ERROR); #endif #ifdef _EMX #ifdef _DJGPP if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0) #else if (__mkdir(Name)==0) #endif { if (SetAttr) SetFileAttr(Name,NameW,Attr); return(MKDIR_SUCCESS); } return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); #endif #ifdef _UNIX mode_t uattr=SetAttr ? (mode_t)Attr:0777; int ErrCode=Name==NULL ? -1:mkdir(Name,uattr); if (ErrCode==-1) return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); return(MKDIR_SUCCESS); #endif }
void ConvertNameToFull(const wchar *Src,wchar *Dest) { if (Src==NULL || *Src==0) { *Dest=0; return; } #ifdef _WIN_32 #ifndef _WIN_CE if (WinNT()) #endif { //#ifndef _WIN_CE #if !defined(_WIN_CE) && !defined(_LINUX) wchar FullName[NM],*NamePtr; if (GetFullPathNameW(Src,sizeof(FullName)/sizeof(FullName[0]),FullName,&NamePtr)) strcpyw(Dest,FullName); else #endif if (Src!=Dest) strcpyw(Dest,Src); } #ifndef _WIN_CE else { char AnsiName[NM]; WideToChar(Src,AnsiName); ConvertNameToFull(AnsiName,AnsiName); CharToWide(AnsiName,Dest); } #endif #else char AnsiName[NM]; WideToChar(Src,AnsiName); ConvertNameToFull(AnsiName,AnsiName); CharToWide(AnsiName,Dest); #endif }
void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta) { #ifdef _WIN_32 if (!WinNT()) return; bool sm=ftm!=NULL && ftm->IsSet(); bool sc=ftc!=NULL && ftc->IsSet(); bool sa=fta!=NULL && fta->IsSet(); unsigned int DirAttr=GetFileAttr(Name,NameW); bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FA_RDONLY)!=0); if (ResetAttr) SetFileAttr(Name,NameW,0); wchar DirNameW[NM]; GetWideName(Name,NameW,DirNameW); HANDLE hFile=CreateFileW(DirNameW,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL); if (hFile==INVALID_HANDLE_VALUE) return; FILETIME fm,fc,fa; if (sm) ftm->GetWin32(&fm); if (sc) ftc->GetWin32(&fc); if (sa) fta->GetWin32(&fa); SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL); CloseHandle(hFile); if (ResetAttr) SetFileAttr(Name,NameW,DirAttr); #endif #if defined(_UNIX) || defined(_EMX) File::SetCloseFileTimeByName(Name,ftm,fta); #endif }
void RarTime::GetLocal(RarLocalTime *lt) { #ifdef _WIN_ALL FILETIME ft; GetWin32(&ft); FILETIME lft; if (WinNT() < WNT_VISTA) { // SystemTimeToTzSpecificLocalTime based code produces 1 hour error on XP. FileTimeToLocalFileTime(&ft,&lft); } else { // We use these functions instead of FileTimeToLocalFileTime according to // MSDN recommendation: "To account for daylight saving time // when converting a file time to a local time ..." SYSTEMTIME st1,st2; FileTimeToSystemTime(&ft,&st1); SystemTimeToTzSpecificLocalTime(NULL,&st1,&st2); SystemTimeToFileTime(&st2,&lft); // Correct precision loss (low 4 decimal digits) in FileTimeToSystemTime. FILETIME rft; SystemTimeToFileTime(&st1,&rft); int64 Corrected=INT32TO64(ft.dwHighDateTime,ft.dwLowDateTime)- INT32TO64(rft.dwHighDateTime,rft.dwLowDateTime)+ INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime); lft.dwLowDateTime=(DWORD)Corrected; lft.dwHighDateTime=(DWORD)(Corrected>>32); } SYSTEMTIME st; FileTimeToSystemTime(&lft,&st); lt->Year=st.wYear; lt->Month=st.wMonth; lt->Day=st.wDay; lt->Hour=st.wHour; lt->Minute=st.wMinute; lt->Second=st.wSecond; lt->wDay=st.wDayOfWeek; lt->yDay=lt->Day-1; static int mdays[12]={31,28,31,30,31,30,31,31,30,31,30,31}; for (uint I=1;I<lt->Month && I<=ASIZE(mdays);I++) lt->yDay+=mdays[I-1]; if (lt->Month>2 && IsLeapYear(lt->Year)) lt->yDay++; st.wMilliseconds=0; FILETIME zft; SystemTimeToFileTime(&st,&zft); // Calculate the time reminder, which is the part of time smaller // than 1 second, represented in 100-nanosecond intervals. lt->Reminder=INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime)- INT32TO64(zft.dwHighDateTime,zft.dwLowDateTime); #else time_t ut=GetUnix(); struct tm *t; t=localtime(&ut); lt->Year=t->tm_year+1900; lt->Month=t->tm_mon+1; lt->Day=t->tm_mday; lt->Hour=t->tm_hour; lt->Minute=t->tm_min; lt->Second=t->tm_sec; lt->Reminder=itime % 10000000; lt->wDay=t->tm_wday; lt->yDay=t->tm_yday; #endif }
void ExtractStreamsNew(Archive& Arc, char* FileName, wchar* FileNameW) { if (!WinNT()) return; wchar NameW[NM]; if (FileNameW != NULL && *FileNameW != 0) wcscpy(NameW, FileNameW); else CharToWide(FileName, NameW); wchar StreamNameW[NM + 2]; if (NameW[0] != 0 && NameW[1] == 0) { wcscpy(StreamNameW, L".\\"); wcscpy(StreamNameW + 2, NameW); } else wcscpy(StreamNameW, NameW); wchar* DestName = StreamNameW + wcslen(StreamNameW); byte* SrcName = &Arc.SubHead.SubData[0]; size_t DestSize = Arc.SubHead.SubData.Size() / 2; if (wcslen(StreamNameW) + DestSize >= ASIZE(StreamNameW)) { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName, St(MStreamBroken), FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } RawToWide(SrcName, DestName, DestSize); DestName[DestSize] = 0; if (*DestName != ':') { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName, St(MStreamBroken), FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } ConvertPath(DestName + 1, DestName + 1); FindData fd; bool Found = FindFile::FastFind(FileName, FileNameW, &fd); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName, FileNameW, fd.FileAttr & ~FILE_ATTRIBUTE_READONLY); char StreamName[NM]; WideToChar(StreamNameW, StreamName); File CurFile; if (CurFile.WCreate(StreamName, StreamNameW) && Arc.ReadSubData(NULL, &CurFile)) CurFile.Close(); File HostFile; if (Found && HostFile.Open(FileName, FileNameW, true, true)) SetFileTime(HostFile.GetHandle(), &fd.ftCreationTime, &fd.ftLastAccessTime, &fd.ftLastWriteTime); // Restoring original file attributes. Important if file was read only // or did not have "Archive" attribute SetFileAttr(FileName, FileNameW, fd.FileAttr); }
HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd) { #ifndef _WIN_CE if (WinNT()) #endif { wchar WideMask[NM]; if (MaskW!=NULL && *MaskW!=0) strcpyw(WideMask,MaskW); else CharToWide(Mask,WideMask); WIN32_FIND_DATAW FindData; if (hFind==INVALID_HANDLE_VALUE) { hFind=FindFirstFileW(WideMask,&FindData); if (hFind==INVALID_HANDLE_VALUE) { int SysErr=GetLastError(); fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND && SysErr!=ERROR_NO_MORE_FILES); } } else if (!FindNextFileW(hFind,&FindData)) { hFind=INVALID_HANDLE_VALUE; fd->Error=GetLastError()!=ERROR_NO_MORE_FILES; } if (hFind!=INVALID_HANDLE_VALUE) { strcpyw(fd->NameW,WideMask); strcpyw(PointToName(fd->NameW),FindData.cFileName); WideToChar(fd->NameW,fd->Name); fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow); fd->FileAttr=FindData.dwFileAttributes; WideToChar(FindData.cAlternateFileName,fd->ShortName); fd->ftCreationTime=FindData.ftCreationTime; fd->ftLastAccessTime=FindData.ftLastAccessTime; fd->ftLastWriteTime=FindData.ftLastWriteTime; fd->mtime=FindData.ftLastWriteTime; fd->ctime=FindData.ftCreationTime; fd->atime=FindData.ftLastAccessTime; fd->FileTime=fd->mtime.GetDos(); #ifndef _WIN_CE if (LowAscii(fd->NameW)) *fd->NameW=0; #endif } } #ifndef _WIN_CE else { char CharMask[NM]; if (Mask!=NULL && *Mask!=0) strcpy(CharMask,Mask); else WideToChar(MaskW,CharMask); WIN32_FIND_DATA FindData; if (hFind==INVALID_HANDLE_VALUE) { hFind=FindFirstFile(CharMask,&FindData); if (hFind==INVALID_HANDLE_VALUE) { int SysErr=GetLastError(); fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND; } } else if (!FindNextFile(hFind,&FindData)) { hFind=INVALID_HANDLE_VALUE; fd->Error=GetLastError()!=ERROR_NO_MORE_FILES; } if (hFind!=INVALID_HANDLE_VALUE) { strcpy(fd->Name,CharMask); strcpy(PointToName(fd->Name),FindData.cFileName); CharToWide(fd->Name,fd->NameW); fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow); fd->FileAttr=FindData.dwFileAttributes; strcpy(fd->ShortName,FindData.cAlternateFileName); fd->ftCreationTime=FindData.ftCreationTime; fd->ftLastAccessTime=FindData.ftLastAccessTime; fd->ftLastWriteTime=FindData.ftLastWriteTime; fd->mtime=FindData.ftLastWriteTime; fd->ctime=FindData.ftCreationTime; fd->atime=FindData.ftLastAccessTime; fd->FileTime=fd->mtime.GetDos(); if (LowAscii(fd->Name)) *fd->NameW=0; } } #endif fd->Flags=0; return(hFind); }
bool ReadTextFile( const char *Name, const wchar *NameW, StringList *List, bool Config, bool AbortOnError, RAR_CHARSET SrcCharset, bool Unquote, bool SkipComments, bool ExpandEnvStr) { char FileName[NM]; *FileName=0; if (Name!=NULL) { if (Config) GetConfigName(Name,FileName,true); else strcpy(FileName,Name); } wchar FileNameW[NM]; *FileNameW=0; #ifdef _WIN_ALL if (NameW!=NULL) { if (Config) GetConfigName(NameW,FileNameW,true); else wcscpy(FileNameW,NameW); } #endif File SrcFile; if ((FileName!=NULL && *FileName!=0) || (FileNameW!=NULL && *FileNameW!=0)) { bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName,FileNameW):SrcFile.Open(FileName,FileNameW,0); if (!OpenCode) { if (AbortOnError) ErrHandler.Exit(RARX_OPEN); return(false); } } else SrcFile.SetHandleType(FILE_HANDLESTD); unsigned int DataSize=0,ReadSize; const int ReadBlock=1024; Array<char> Data(ReadBlock+5); while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0) { DataSize+=ReadSize; Data.Add(ReadSize); } memset(&Data[DataSize],0,5); if ((SrcCharset==RCH_UNICODE) || (SrcCharset==RCH_DEFAULT && IsUnicode((byte *)&Data[0],DataSize))) { // Unicode in native system format, can be more than 2 bytes per character. Array<wchar> DataW(Data.Size()/2+1); for (size_t I=2;I<Data.Size()-1;I+=2) { // Need to convert Data to (byte) first to prevent the sign extension // to higher bytes. DataW[(I-2)/2]=(wchar)((byte)Data[I])+(wchar)((byte)Data[I+1])*256; } wchar *CurStr=&DataW[0]; Array<char> AnsiName; while (*CurStr!=0) { wchar *NextStr=CurStr,*CmtPtr=NULL; while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) { if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') { *NextStr=0; CmtPtr=NextStr; } NextStr++; } *NextStr=0; for (wchar *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) { if (*SpacePtr!=' ' && *SpacePtr!='\t') break; *SpacePtr=0; } if (*CurStr) { // Length and AddSize must be defined as signed, because AddSize // can be negative. int Length=(int)wcslen(CurStr); int AddSize=4*(Length-(int)AnsiName.Size()+1); if (AddSize>0) AnsiName.Add(AddSize); if (Unquote && *CurStr=='\"' && CurStr[Length-1]=='\"') { CurStr[Length-1]=0; CurStr++; } WideToChar(CurStr,&AnsiName[0],AnsiName.Size()); bool Expanded=false; #if defined(_WIN_ALL) && !defined(_WIN_CE) if (ExpandEnvStr && *CurStr=='%') { // Expanding environment variables in Windows version. char ExpName[NM]; wchar ExpNameW[NM]; *ExpNameW=0; int ret,retw=1; ret=ExpandEnvironmentStringsA(&AnsiName[0],ExpName,ASIZE(ExpName)); if (ret!=0 && WinNT()) retw=ExpandEnvironmentStringsW(CurStr,ExpNameW,ASIZE(ExpNameW)); Expanded=ret!=0 && ret<ASIZE(ExpName) && retw!=0 && retw<ASIZE(ExpNameW); if (Expanded) List->AddString(ExpName,ExpNameW); } #endif if (!Expanded) List->AddString(&AnsiName[0],CurStr); } CurStr=NextStr+1; while (*CurStr=='\r' || *CurStr=='\n') CurStr++; } } else { char *CurStr=&Data[0]; while (*CurStr!=0) { char *NextStr=CurStr,*CmtPtr=NULL; while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) { if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') { *NextStr=0; CmtPtr=NextStr; } NextStr++; } *NextStr=0; for (char *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) { if (*SpacePtr!=' ' && *SpacePtr!='\t') break; *SpacePtr=0; } if (*CurStr) { if (Unquote && *CurStr=='\"') { size_t Length=strlen(CurStr); if (CurStr[Length-1]=='\"') { CurStr[Length-1]=0; CurStr++; } } #if defined(_WIN_ALL) if (SrcCharset==RCH_OEM) OemToCharA(CurStr,CurStr); #endif bool Expanded=false; #if defined(_WIN_ALL) && !defined(_WIN_CE) if (ExpandEnvStr && *CurStr=='%') { // Expanding environment variables in Windows version. char ExpName[NM]; int ret=ExpandEnvironmentStringsA(CurStr,ExpName,ASIZE(ExpName)); Expanded=ret!=0 && ret<ASIZE(ExpName); if (Expanded) List->AddString(ExpName); } #endif if (!Expanded) List->AddString(CurStr); } CurStr=NextStr+1; while (*CurStr=='\r' || *CurStr=='\n') CurStr++; } } return(true); }
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,bool &Repeat) { char Command=*Cmd->Command; if (HeaderSize==0) if (DataIO.UnpVolume) { #ifdef NOVOLUME return(false); #else if (!MergeArchive(Arc,&DataIO,false,Command)) { ErrHandler.SetErrorCode(WARNING); return(false); } SignatureFound=false; #endif } else return(false); int HeadType=Arc.GetHeaderType(); if (HeadType!=FILE_HEAD) { if (HeadType==AV_HEAD || HeadType==SIGN_HEAD) SignatureFound=true; #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (HeadType==SUB_HEAD && PrevExtracted) SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL); #endif if (HeadType==NEWSUB_HEAD) { if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV)) SignatureFound=true; #if !defined(NOSUBBLOCKS) && !defined(_WIN_CE) if (PrevExtracted) SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL); #endif } if (HeadType==ENDARC_HEAD) if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME) { #ifndef NOVOLUME if (!MergeArchive(Arc,&DataIO,false,Command)) { ErrHandler.SetErrorCode(WARNING); return(false); } SignatureFound=false; #endif Arc.Seek(Arc.CurBlockPos,SEEK_SET); return(true); } else return(false); Arc.SeekToNext(); return(true); } PrevExtracted=false; if (SignatureFound || !Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() && AllMatchesExact) return(false); char ArcFileName[NM]; IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName); strcpy(ArcFileName,Arc.NewLhd.FileName); wchar ArcFileNameW[NM]; *ArcFileNameW=0; int MatchType=MATCH_WILDSUBPATH; bool EqualNames=false; int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType); bool ExactMatch=MatchNumber!=0; #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (Cmd->ExclPath==EXCL_BASEPATH) { *Cmd->ArcPath=0; if (ExactMatch) { Cmd->FileArgs->Rewind(); if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1)) *PointToName(Cmd->ArcPath)=0; } } #endif if (ExactMatch && !EqualNames) AllMatchesExact=false; #ifdef UNICODE_SUPPORTED bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled(); #else bool WideName=false; #endif #ifdef _APPLE if (WideName) { WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,sizeof(ArcFileName)); WideName=false; } #endif wchar *DestNameW=WideName ? DestFileNameW:NULL; #ifdef UNICODE_SUPPORTED if (WideName) { ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW); char Name[NM]; if (WideToChar(ArcFileNameW,Name) && IsNameUsable(Name)) strcpy(ArcFileName,Name); } #endif ConvertPath(ArcFileName,ArcFileName); if (Arc.IsArcLabel()) return(true); if (Arc.NewLhd.Flags & LHD_VERSION) { if (Cmd->VersionControl!=1 && !EqualNames) { if (Cmd->VersionControl==0) ExactMatch=false; int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false); if (Cmd->VersionControl-1==Version) ParseVersionFileName(ArcFileName,ArcFileNameW,true); else ExactMatch=false; } } else if (!Arc.IsArcDir() && Cmd->VersionControl>1) ExactMatch=false; Arc.ConvertAttributes(); #ifndef SFX_MODULE if ((Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/)) && FirstFile) { char CurVolName[NM]; strcpy(CurVolName,ArcName); VolNameToFirstName(ArcName,ArcName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0); if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName)) { *ArcNameW=0; Repeat=true; return(false); } #if !defined(RARDLL) && !defined(_WIN_CE) if (!ReconstructDone) { ReconstructDone=true; RecVolumes RecVol; if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true)) { Repeat=true; return(false); } } #endif strcpy(ArcName,CurVolName); } #endif DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0; DataIO.NextVolumeMissing=false; Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); bool TestMode=false; bool ExtrFile=false; bool SkipSolid=false; #ifndef SFX_MODULE if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0) { if (ExactMatch) { Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName); #ifdef RARDLL Cmd->DllError=ERAR_BAD_DATA; #endif ErrHandler.SetErrorCode(OPEN_ERROR); } ExactMatch=false; } FirstFile=false; #endif if (ExactMatch || (SkipSolid=Arc.Solid)!=0) { if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0) #ifndef RARDLL if (*Password==0) #endif { #ifdef RARDLL if (*Cmd->Password==0) if (Cmd->Callback==NULL || Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)Cmd->Password,sizeof(Cmd->Password))==-1) return(false); strcpy(Password,Cmd->Password); #else if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password))) { PasswordCancelled=true; return(false); } #endif } #if !defined(GUI) && !defined(SILENT) else if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0)) { eprintf(St(MUseCurPsw),ArcFileName); switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll))) { case -1: ErrHandler.Exit(USER_BREAK); case 2: if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password))) { return(false); } break; case 3: PasswordAll=true; break; } } #endif #ifndef SFX_MODULE if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0) WideToChar(Cmd->ExtrPathW,DestFileName); else #endif strcpy(DestFileName,Cmd->ExtrPath); #ifndef SFX_MODULE if (Cmd->AppendArcNameToPath) { strcat(DestFileName,PointToName(Arc.FirstVolumeName)); SetExt(DestFileName,NULL); AddEndSlash(DestFileName); } #endif char *ExtrName=ArcFileName; bool EmptyName=false; #ifndef SFX_MODULE size_t Length=strlen(Cmd->ArcPath); if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) && strlen(ArcFileName)==Length-1) Length--; if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0) { ExtrName+=Length; while (*ExtrName==CPATHDIVIDER) ExtrName++; if (*ExtrName==0) EmptyName=true; } #endif bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':'); if (AbsPaths) *DestFileName=0; if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) strcat(DestFileName,PointToName(ExtrName)); else strcat(DestFileName,ExtrName); char DiskLetter=etoupper(DestFileName[0]); if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) && DiskLetter>='A' && DiskLetter<='Z') DestFileName[1]=':'; #ifndef SFX_MODULE if (!WideName && *Cmd->ExtrPathW!=0) { DestNameW=DestFileNameW; WideName=true; CharToWide(ArcFileName,ArcFileNameW); } #endif if (WideName) { if (*Cmd->ExtrPathW!=0) strcpyw(DestFileNameW,Cmd->ExtrPathW); else CharToWide(Cmd->ExtrPath,DestFileNameW); #ifndef SFX_MODULE if (Cmd->AppendArcNameToPath) { wchar FileNameW[NM]; if (*Arc.FirstVolumeNameW!=0) strcpyw(FileNameW,Arc.FirstVolumeNameW); else CharToWide(Arc.FirstVolumeName,FileNameW); strcatw(DestFileNameW,PointToName(FileNameW)); SetExt(DestFileNameW,NULL); AddEndSlash(DestFileNameW); } #endif wchar *ExtrNameW=ArcFileNameW; #ifndef SFX_MODULE if (Length>0) { wchar ArcPathW[NM]; GetWideName(Cmd->ArcPath,Cmd->ArcPathW,ArcPathW); Length=strlenw(ArcPathW); } ExtrNameW+=Length; while (*ExtrNameW==CPATHDIVIDER) ExtrNameW++; #endif if (AbsPaths) *DestFileNameW=0; if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) strcatw(DestFileNameW,PointToName(ExtrNameW)); else strcatw(DestFileNameW,ExtrNameW); if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2])) DestFileNameW[1]=':'; } else *DestFileNameW=0; ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0; if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X')) { struct FindData FD; if (FindFile::FastFind(DestFileName,DestNameW,&FD)) { if (FD.mtime >= Arc.NewLhd.mtime) { // If directory already exists and its modification time is newer // than start of extraction, it is likely it was created // when creating a path to one of already extracted items. // In such case we'll better update its time even if archived // directory is older. if (!FD.IsDir || FD.mtime<StartTime) ExtrFile=false; } } else if (Cmd->FreshFiles) ExtrFile=false; } // Skip encrypted file if no password is specified. if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && *Password==0) { ErrHandler.SetErrorCode(WARNING); #ifdef RARDLL Cmd->DllError=ERAR_MISSING_PASSWORD; #endif ExtrFile=false; } #ifdef RARDLL if (*Cmd->DllDestName) { strncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName)); *DestFileNameW=0; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } if (*Cmd->DllDestNameW) { strncpyzw(DestFileNameW,Cmd->DllDestNameW,ASIZE(DestFileNameW)); DestNameW=DestFileNameW; if (Cmd->DllOpMode!=RAR_EXTRACT) ExtrFile=false; } #endif #ifdef SFX_MODULE if ((Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.UnpVer!=29) && Arc.NewLhd.Method!=0x30) #else if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER) #endif { #ifndef SILENT Log(Arc.FileName,St(MUnknownMeth),ArcFileName); #ifndef SFX_MODULE Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10); #endif #endif ExtrFile=false; ErrHandler.SetErrorCode(WARNING); #ifdef RARDLL Cmd->DllError=ERAR_UNKNOWN_FORMAT; #endif } File CurFile; if (!IsLink(Arc.NewLhd.FileAttr)) if (Arc.IsArcDir()) { if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) return(true); if (SkipSolid) { #ifndef GUI mprintf(St(MExtrSkipFile),ArcFileName); #endif return(true); } TotalFileCount++; if (Cmd->Test) { #ifndef GUI mprintf(St(MExtrTestFile),ArcFileName); mprintf(" %s",St(MOk)); #endif return(true); } MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr); bool DirExist=false; if (MDCode!=MKDIR_SUCCESS) { DirExist=FileExist(DestFileName,DestNameW); if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW))) { bool UserReject; FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime); DirExist=false; } CreatePath(DestFileName,DestNameW,true); MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr); } if (MDCode==MKDIR_SUCCESS) { #ifndef GUI mprintf(St(MCreatDir),DestFileName); mprintf(" %s",St(MOk)); #endif PrevExtracted=true; } else if (DirExist) { if (!Cmd->IgnoreGeneralAttr) SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr); PrevExtracted=true; } else { Log(Arc.FileName,St(MExtrErrMkDir),DestFileName); ErrHandler.SysErrMsg(); #ifdef RARDLL Cmd->DllError=ERAR_ECREATE; #endif ErrHandler.SetErrorCode(CREATE_ERROR); } if (PrevExtracted) { #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) if (Cmd->SetCompressedAttr && (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) SetFileCompression(DestFileName,DestNameW,true); #endif SetDirTime(DestFileName,DestNameW, Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); } return(true); } else { if (Cmd->Test && ExtrFile) TestMode=true; #if !defined(GUI) && !defined(SFX_MODULE) if (Command=='P' && ExtrFile) CurFile.SetHandleType(FILE_HANDLESTD); #endif if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test) { bool UserReject; if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime)) { ExtrFile=false; if (!UserReject) { ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName); ErrHandler.SetErrorCode(CREATE_ERROR); #ifdef RARDLL Cmd->DllError=ERAR_ECREATE; #endif if (!IsNameUsable(DestFileName)) { Log(Arc.FileName,St(MCorrectingName)); char OrigName[sizeof(DestFileName)]; strncpyz(OrigName,DestFileName,ASIZE(OrigName)); MakeNameUsable(DestFileName,true); CreatePath(DestFileName,NULL,true); if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime)) { #ifndef SFX_MODULE Log(Arc.FileName,St(MRenaming),OrigName,DestFileName); #endif ExtrFile=true; } else ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName); } } } } } if (!ExtrFile && Arc.Solid) { SkipSolid=true; TestMode=true; ExtrFile=true; } if (ExtrFile) { if (!SkipSolid) { if (!TestMode && Command!='P' && CurFile.IsDevice()) { Log(Arc.FileName,St(MInvalidName),DestFileName); ErrHandler.WriteError(Arc.FileName,DestFileName); } TotalFileCount++; } FileCount++; #ifndef GUI if (Command!='I') if (SkipSolid) mprintf(St(MExtrSkipFile),ArcFileName); else switch(Cmd->Test ? 'T':Command) { case 'T': mprintf(St(MExtrTestFile),ArcFileName); break; #ifndef SFX_MODULE case 'P': mprintf(St(MExtrPrinting),ArcFileName); break; #endif case 'X': case 'E': mprintf(St(MExtrFile),DestFileName); break; } if (!Cmd->DisablePercentage) mprintf(" "); #endif DataIO.CurUnpRead=0; DataIO.CurUnpWrite=0; DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff; DataIO.PackedCRC=0xffffffff; DataIO.SetEncryption( (Arc.NewLhd.Flags & LHD_PASSWORD) ? Arc.NewLhd.UnpVer:0,Password, (Arc.NewLhd.Flags & LHD_SALT) ? Arc.NewLhd.Salt:NULL,false, Arc.NewLhd.UnpVer>=36); DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize); DataIO.SetFiles(&Arc,&CurFile); DataIO.SetTestMode(TestMode); DataIO.SetSkipUnpCRC(SkipSolid); #ifndef _WIN_CE if (!TestMode && !Arc.BrokenFileHeader && (Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize && (Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize)) CurFile.Prealloc(Arc.NewLhd.FullUnpSize); #endif CurFile.SetAllowDelete(!Cmd->KeepBroken); bool LinkCreateMode=!Cmd->Test && !SkipSolid; if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode)) PrevExtracted=LinkCreateMode; else if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0) if (Arc.NewLhd.Method==0x30) UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize); else { Unp->SetDestSize(Arc.NewLhd.FullUnpSize); #ifndef SFX_MODULE if (Arc.NewLhd.UnpVer<=15) Unp->DoUnpack(15,FileCount>1 && Arc.Solid); else #endif Unp->DoUnpack(Arc.NewLhd.UnpVer,(Arc.NewLhd.Flags & LHD_SOLID)!=0); } if (Arc.IsOpened()) Arc.SeekToNext(); bool BrokenFile=false; if (!SkipSolid) { if (Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC) || !Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC^0xffffffff)) { #ifndef GUI if (Command!='P' && Command!='I') mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk)); #endif } else { char *BadArcName=/*(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE) ? NULL:*/Arc.FileName; if (Arc.NewLhd.Flags & LHD_PASSWORD) { Log(BadArcName,St(MEncrBadCRC),ArcFileName); } else { Log(BadArcName,St(MCRCFailed),ArcFileName); } BrokenFile=true; ErrHandler.SetErrorCode(CRC_ERROR); #ifdef RARDLL Cmd->DllError=ERAR_BAD_DATA; #endif Alarm(); } } #ifndef GUI else mprintf("\b\b\b\b\b "); #endif if (!TestMode && (Command=='X' || Command=='E') && !IsLink(Arc.NewLhd.FileAttr)) { #if defined(_WIN_32) || defined(_EMX) if (Cmd->ClearArc) Arc.NewLhd.FileAttr&=~FA_ARCH; /* else Arc.NewLhd.FileAttr|=FA_ARCH; //set archive bit for unpacked files (file is not backed up) */ #endif if (!BrokenFile || Cmd->KeepBroken) { if (BrokenFile) CurFile.Truncate(); CurFile.SetOpenFileTime( Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); CurFile.Close(); #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) if (Cmd->SetCompressedAttr && (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) SetFileCompression(CurFile.FileName,CurFile.FileNameW,true); #endif CurFile.SetCloseFileTime( Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); if (!Cmd->IgnoreGeneralAttr) SetFileAttr(CurFile.FileName,CurFile.FileNameW,Arc.NewLhd.FileAttr); PrevExtracted=true; } } } } if (ExactMatch) MatchedArgs++; if (DataIO.NextVolumeMissing || !Arc.IsOpened()) return(false); if (!ExtrFile) if (!Arc.Solid) Arc.SeekToNext(); else if (!SkipSolid) return(false); return(true); }
void ExtractStreams(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; if (Arc.HeaderCRC!=Arc.StreamHead.HeadCRC) { #ifndef SILENT Log(Arc.FileName,St(MStreamBroken),FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } if (Arc.StreamHead.Method<0x31 || Arc.StreamHead.Method>0x35 || Arc.StreamHead.UnpVer>PACK_VER) { #ifndef SILENT Log(Arc.FileName,St(MStreamUnknown),FileName); #endif ErrHandler.SetErrorCode(WARNING); return; } char StreamName[NM+2]; if (FileName[0]!=0 && FileName[1]==0) { strcpy(StreamName,".\\"); strcpy(StreamName+2,FileName); } else strcpy(StreamName,FileName); if (strlen(StreamName)+strlen((char *)Arc.StreamHead.StreamName)>=sizeof(StreamName)) { #ifndef SILENT Log(Arc.FileName,St(MStreamBroken),FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } strcat(StreamName,(char *)Arc.StreamHead.StreamName); FindData fd; bool Found=FindFile::FastFind(FileName,FileNameW,&fd); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY); File CurFile; if (CurFile.WCreate(StreamName)) { ComprDataIO DataIO; Unpack Unpack(&DataIO); Unpack.Init(); Array<unsigned char> UnpData(Arc.StreamHead.UnpSize); DataIO.SetPackedSizeToRead(Arc.StreamHead.DataSize); DataIO.EnableShowProgress(false); DataIO.SetFiles(&Arc,&CurFile); Unpack.SetDestSize(Arc.StreamHead.UnpSize); Unpack.DoUnpack(Arc.StreamHead.UnpVer,false); if (Arc.StreamHead.StreamCRC!=~DataIO.UnpFileCRC) { #ifndef SILENT Log(Arc.FileName,St(MStreamBroken),StreamName); #endif ErrHandler.SetErrorCode(CRC_ERROR); } else CurFile.Close(); } File HostFile; if (Found && HostFile.Open(FileName,FileNameW,true,true)) SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime, &fd.ftLastWriteTime); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr); }
void CmdExtract::ExtrCreateDir(Archive &Arc,const wchar *ArcFileName) { if (Cmd->Test) { #ifndef GUI mprintf(St(MExtrTestFile),ArcFileName); mprintf(L" %s",St(MOk)); #endif return; } MKDIR_CODE MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr); bool DirExist=false; if (MDCode!=MKDIR_SUCCESS) { DirExist=FileExist(DestFileName); if (DirExist && !IsDir(GetFileAttr(DestFileName))) { // File with name same as this directory exists. Propose user // to overwrite it. bool UserReject; FileCreate(Cmd,NULL,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime); DirExist=false; } if (!DirExist) { CreatePath(DestFileName,true); MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr); if (MDCode!=MKDIR_SUCCESS) { wchar OrigName[ASIZE(DestFileName)]; wcsncpyz(OrigName,DestFileName,ASIZE(OrigName)); MakeNameUsable(DestFileName,true); CreatePath(DestFileName,true); MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr); #ifndef SFX_MODULE if (MDCode==MKDIR_SUCCESS) uiMsg(UIERROR_RENAMING,Arc.FileName,OrigName,DestFileName); #endif } } } if (MDCode==MKDIR_SUCCESS) { #ifndef GUI mprintf(St(MCreatDir),DestFileName); mprintf(L" %s",St(MOk)); #endif PrevExtracted=true; } else if (DirExist) { if (!Cmd->IgnoreGeneralAttr) SetFileAttr(DestFileName,Arc.FileHead.FileAttr); PrevExtracted=true; } else { uiMsg(UIERROR_DIRCREATE,Arc.FileName,DestFileName); ErrHandler.SysErrMsg(); #ifdef RARDLL Cmd->DllError=ERAR_ECREATE; #endif ErrHandler.SetErrorCode(RARX_CREATE); } if (PrevExtracted) { #if defined(_WIN_ALL) && !defined(SFX_MODULE) if (Cmd->SetCompressedAttr && (Arc.FileHead.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) SetFileCompression(DestFileName,true); #endif SetDirTime(DestFileName, Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime, Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.FileHead.ctime, Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime); } }
bool File::Open(const char *Name,const wchar *NameW,bool OpenShared,bool Update) { ErrorType=FILE_SUCCESS; FileHandle hNewFile; if (File::OpenShared) OpenShared=true; #ifdef _WIN_32 uint Access=GENERIC_READ; if (Update) Access|=GENERIC_WRITE; uint ShareMode=FILE_SHARE_READ; if (OpenShared) ShareMode|=FILE_SHARE_WRITE; if (WinNT() && NameW!=NULL && *NameW!=0) hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,NULL); else hNewFile=CreateFile(Name,Access,ShareMode,NULL,OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,NULL); if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND) ErrorType=FILE_NOTFOUND; #else int flags=Update ? O_RDWR:O_RDONLY; #ifdef O_BINARY flags|=O_BINARY; #if defined(_AIX) && defined(_LARGE_FILE_API) flags|=O_LARGEFILE; #endif #endif #if defined(_EMX) && !defined(_DJGPP) int sflags=OpenShared ? SH_DENYNO:SH_DENYWR; int handle=sopen(Name,flags,sflags); #else int handle=open(Name,flags); #ifdef LOCK_EX if (!OpenShared && Update && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1) { close(handle); return(false); } #endif #endif hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,Update ? UPDATEBINARY:READBINARY); if (hNewFile==BAD_HANDLE && errno==ENOENT) ErrorType=FILE_NOTFOUND; #endif NewFile=false; HandleType=FILE_HANDLENORMAL; SkipClose=false; bool Success=hNewFile!=BAD_HANDLE; if (Success) { hFile=hNewFile; if (NameW!=NULL) strcpyw(FileNameW,NameW); else *FileNameW=0; if (Name!=NULL) strcpy(FileName,Name); else WideToChar(NameW,FileName); AddFileToList(hFile); } return(Success); }