1 #include "rar.hpp"
2
3 static void GetFirstNewVolName(const char *ArcName,char *VolName,
4 Int64 VolSize,Int64 TotalSize);
5
6
7
MergeArchive(Archive & Arc,ComprDataIO * DataIO,bool ShowFileName,char Command)8 bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command)
9 {
10 RAROptions *Cmd=Arc.GetRAROptions();
11
12 int HeaderType=Arc.GetHeaderType();
13 FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd;
14 bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) &&
15 (hd->Flags & LHD_SPLIT_AFTER)!=0;
16
17 if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 &&
18 hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC)
19 {
20 Log(Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName);
21 }
22
23 Int64 PosBeforeClose=Arc.Tell();
24 Arc.Close();
25
26 char NextName[NM];
27 strcpy(NextName,Arc.FileName);
28 NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);
29
30 #if !defined(SFX_MODULE) && !defined(RARDLL)
31 bool RecoveryDone=false;
32 #endif
33 bool FailedOpen=false,OldSchemeTested=false;
34
35 while (!Arc.Open(NextName))
36 {
37 if (!OldSchemeTested)
38 {
39 char AltNextName[NM];
40 strcpy(AltNextName,Arc.FileName);
41 NextVolumeName(AltNextName,true);
42 OldSchemeTested=true;
43 if (Arc.Open(AltNextName))
44 {
45 strcpy(NextName,AltNextName);
46 break;
47 }
48 }
49 #ifdef RARDLL
50 if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL ||
51 Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1)
52 {
53 Cmd->DllError=ERAR_EOPEN;
54 FailedOpen=true;
55 break;
56 }
57 if (Cmd->ChangeVolProc!=NULL)
58 {
59 //#ifdef _WIN_32
60 // _EBX=_ESP;
61 //#endif
62 int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK);
63 //#ifdef _WIN_32
64 // _ESP=_EBX;
65 //#endif
66 if (RetCode==0)
67 {
68 Cmd->DllError=ERAR_EOPEN;
69 FailedOpen=true;
70 break;
71 }
72 }
73 #else
74
75 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
76 if (!RecoveryDone)
77 {
78 RecVolumes RecVol;
79 RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true);
80 RecoveryDone=true;
81 continue;
82 }
83 #endif
84
85 #ifndef GUI
86 if (!Cmd->VolumePause && !IsRemovable(NextName))
87 {
88 Log(Arc.FileName,St(MAbsNextVol),NextName);
89 FailedOpen=true;
90 break;
91 }
92 #endif
93 #ifndef SILENT
94 if (Cmd->AllYes || !AskNextVol(NextName))
95 #endif
96 {
97 FailedOpen=true;
98 break;
99 }
100 #endif
101 }
102 if (FailedOpen)
103 {
104 Arc.Open(Arc.FileName,Arc.FileNameW);
105 Arc.Seek(PosBeforeClose,SEEK_SET);
106 return(false);
107 }
108 Arc.CheckArc(true);
109 #ifdef RARDLL
110 if (Cmd->Callback!=NULL &&
111 Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_NOTIFY)==-1)
112 return(false);
113 if (Cmd->ChangeVolProc!=NULL)
114 {
115 //#ifdef _WIN_32
116 // _EBX=_ESP;
117 //#endif
118 int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_NOTIFY);
119 //#ifdef _WIN_32
120 // _ESP=_EBX;
121 //#endif
122 if (RetCode==0)
123 return(false);
124 }
125 #endif
126
127 if (Command=='T' || Command=='X' || Command=='E')
128 mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName);
129 if (SplitHeader)
130 Arc.SearchBlock(HeaderType);
131 else
132 Arc.ReadHeader();
133 if (Arc.GetHeaderType()==FILE_HEAD)
134 {
135 Arc.ConvertAttributes();
136 Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET);
137 }
138 #ifndef GUI
139 if (ShowFileName)
140 {
141 mprintf(St(MExtrPoints),IntNameToExt(Arc.NewLhd.FileName));
142 if (!Cmd->DisablePercentage)
143 mprintf(" ");
144 }
145 #endif
146 if (DataIO!=NULL)
147 {
148 if (HeaderType==ENDARC_HEAD)
149 DataIO->UnpVolume=false;
150 else
151 {
152 DataIO->UnpVolume=(hd->Flags & LHD_SPLIT_AFTER);
153 DataIO->SetPackedSizeToRead(hd->FullPackSize);
154 }
155 #ifdef SFX_MODULE
156 DataIO->UnpArcSize=Arc.FileLength();
157 DataIO->CurUnpRead=0;
158 #endif
159 DataIO->PackedCRC=0xffffffff;
160 // DataIO->SetFiles(&Arc,NULL);
161 }
162 return(true);
163 }
164
165
166
167
168
169
170 #ifndef SILENT
AskNextVol(char * ArcName)171 bool AskNextVol(char *ArcName)
172 {
173 eprintf(St(MAskNextVol),ArcName);
174 if (Ask(St(MContinueQuit))==2)
175 return(false);
176 return(true);
177 }
178 #endif
179