#include "rar.hpp" bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW, OVERWRITE_MODE Mode,bool *UserReject,int64 FileSize, uint FileTime) { if (UserReject!=NULL) *UserReject=false; #if defined(_WIN_32) && !defined(_WIN_CE) bool ShortNameChanged=false; #endif while (FileExist(Name,NameW)) { #if defined(_WIN_32) && !defined(_WIN_CE) if (!ShortNameChanged) { ShortNameChanged=true; if (UpdateExistingShortName(Name,NameW)) continue; } #endif if (Mode==OVERWRITE_NONE) { if (UserReject!=NULL) *UserReject=true; return(false); } #ifdef SILENT Mode=OVERWRITE_ALL; #endif if (Cmd->AllYes || Mode==OVERWRITE_ALL) break; if (Mode==OVERWRITE_DEFAULT || Mode==OVERWRITE_FORCE_ASK) { eprintf(St(MFileExists),Name); int Choice=Ask(St(MYesNoAllRenQ)); if (Choice==1) break; if (Choice==2) { if (UserReject!=NULL) *UserReject=true; return(false); } if (Choice==3) { Cmd->Overwrite=OVERWRITE_ALL; break; } if (Choice==4) { if (UserReject!=NULL) *UserReject=true; Cmd->Overwrite=OVERWRITE_NONE; return(false); } if (Choice==5) { mprintf(St(MAskNewName)); char NewName[NM]; #ifdef _WIN_32 File SrcFile; SrcFile.SetHandleType(FILE_HANDLESTD); int Size=SrcFile.Read(NewName,sizeof(NewName)-1); NewName[Size]=0; OemToChar(NewName,NewName); #else if (fgets(NewName,sizeof(NewName),stdin)==NULL) { // Process fgets failure as if user answered 'No'. if (UserReject!=NULL) *UserReject=true; return(false); } #endif RemoveLF(NewName); if (PointToName(NewName)==NewName) strcpy(PointToName(Name),NewName); else strcpy(Name,NewName); if (NameW!=NULL) *NameW=0; continue; } if (Choice==6) ErrHandler.Exit(USER_BREAK); } if (Mode==OVERWRITE_AUTORENAME) { if (GetAutoRenamedName(Name)) { if (NameW!=NULL) *NameW=0; } else Mode=OVERWRITE_DEFAULT; continue; } } if (NewFile!=NULL && NewFile->Create(Name,NameW)) return(true); PrepareToDelete(Name,NameW); CreatePath(Name,NameW,true); return(NewFile!=NULL ? NewFile->Create(Name,NameW):DelFile(Name,NameW)); } bool GetAutoRenamedName(char *Name) { char NewName[NM]; if (strlen(Name)>sizeof(NewName)-10) return(false); char *Ext=GetExt(Name); if (Ext==NULL) Ext=Name+strlen(Name); for (int FileVer=1;;FileVer++) { sprintf(NewName,"%.*s(%d)%s",int(Ext-Name),Name,FileVer,Ext); if (!FileExist(NewName)) { strcpy(Name,NewName); break; } if (FileVer>=1000000) return(false); } return(true); } #if defined(_WIN_32) && !defined(_WIN_CE) bool UpdateExistingShortName(char *Name,wchar *NameW) { FindData fd; if (!FindFile::FastFind(Name,NameW,&fd)) return(false); if (*fd.Name==0 || *fd.ShortName==0) return(false); if (stricomp(PointToName(fd.Name),fd.ShortName)==0 || stricomp(PointToName(Name),fd.ShortName)!=0) return(false); char NewName[NM]; for (int I=0;I<10000;I+=123) { strncpyz(NewName,Name,ASIZE(NewName)); sprintf(PointToName(NewName),"rtmp%d",I); if (!FileExist(NewName)) break; } if (FileExist(NewName)) return(false); char FullName[NM]; strncpyz(FullName,Name,ASIZE(FullName)); strcpy(PointToName(FullName),PointToName(fd.Name)); if (!MoveFile(FullName,NewName)) return(false); File KeepShortFile; bool Created=false; if (!FileExist(Name)) Created=KeepShortFile.Create(Name); MoveFile(NewName,FullName); if (Created) { KeepShortFile.Close(); KeepShortFile.Delete(); } return(true); } /* bool UpdateExistingShortName(char *Name,wchar *NameW) { if (WinNT()<5) return(false); FindData fd; if (!FindFile::FastFind(Name,NameW,&fd)) return(false); if (*fd.Name==0 || *fd.ShortName==0) return(false); if (stricomp(PointToName(fd.Name),fd.ShortName)==0 || stricomp(PointToName(Name),fd.ShortName)!=0) return(false); typedef BOOL (WINAPI *SETFILESHORTNAME)(HANDLE,LPCSTR); static SETFILESHORTNAME pSetFileShortName=NULL; if (pSetFileShortName==NULL) { HMODULE hKernel=GetModuleHandle("kernel32.dll"); if (hKernel!=NULL) pSetFileShortName=(SETFILESHORTNAME)GetProcAddress(hKernel,"SetFileShortNameA"); if (pSetFileShortName==NULL) return(false); } static bool RestoreEnabled=false; if (!RestoreEnabled) { HANDLE hToken; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return(false); TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (LookupPrivilegeValue(NULL,SE_RESTORE_NAME,&tp.Privileges[0].Luid)) AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL); CloseHandle(hToken); RestoreEnabled=true; } wchar FileNameW[NM]; GetWideName(Name,NameW,FileNameW); HANDLE hFile=CreateFileW(FileNameW,GENERIC_WRITE|DELETE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL); if (hFile==INVALID_HANDLE_VALUE) return(false); bool RetCode=false; char FullName[NM]; wchar FullNameW[NM]; strcpy(FullName,Name); strcpyw(FullNameW,NullToEmpty(NameW)); for (int I=1;I<1000000;I++) { char NewName[NM]; sprintf(NewName,"NAME~%d.%d",I%1000,I/1000+1); strcpy(PointToName(FullName),NewName); if (*FullNameW) CharToWide(NewName,PointToName(FullNameW)); if (!FileExist(FullName,FullNameW)) { RetCode=pSetFileShortName(hFile,NewName); break; } } CloseHandle(hFile); return(RetCode); } */ #endif