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