~ubuntu-branches/ubuntu/vivid/unrar-nonfree/vivid

« back to all changes in this revision

Viewing changes to archive.cpp

  • Committer: Package Import Robot
  • Author(s): Martin Meredith
  • Date: 2015-02-03 12:58:01 UTC
  • mfrom: (1.1.18) (5.1.18 sid)
  • Revision ID: package-import@ubuntu.com-20150203125801-od6ev8cqy1er51vz
Tags: 1:5.2.5-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
  NewArchive=false;
50
50
 
51
51
  SilentOpen=false;
 
52
 
52
53
}
53
54
 
54
55
 
67
68
    // If FailedHeaderDecryption is set, we already reported that archive
68
69
    // password is incorrect.
69
70
    if (!FailedHeaderDecryption)
70
 
    {
71
 
      Log(FileName,St(MBadArc),FileName);
72
 
    }
 
71
      uiMsg(UIERROR_BADARCHIVE,FileName);
73
72
    ErrHandler.Exit(RARX_FATAL);
74
73
  }
75
74
}
91
90
    return false;
92
91
  if (!IsArchive(false))
93
92
  {
94
 
#ifndef SHELL_EXT
95
 
    Log(FileName,St(MNotRAR),FileName);
96
 
#endif
 
93
    uiMsg(UIERROR_BADARCHIVE,FileName);
97
94
    Close();
98
95
    return false;
99
96
  }
131
128
bool Archive::IsArchive(bool EnableBroken)
132
129
{
133
130
  Encrypted=false;
134
 
#ifdef USE_QOPEN
135
 
  QOpen.Unload();
136
 
#endif
137
 
 
138
 
  // Important if we reuse Archive object and it has virtual QOpen
139
 
  // file position not matching real. For example, for 'l -v volname'.
140
 
  Seek(0,SEEK_SET);
 
131
  BrokenHeader=false; // Might be left from previous volume.
141
132
  
142
133
#ifndef SFX_MODULE
143
134
  if (IsDevice())
144
135
  {
145
 
#ifndef SHELL_EXT
146
 
    Log(FileName,St(MInvalidName),FileName);
147
 
#endif
 
136
    uiMsg(UIERROR_INVALIDNAME,FileName,FileName);
148
137
    return false;
149
138
  }
150
139
#endif
151
140
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD3)!=SIZEOF_MARKHEAD3)
152
 
    return(false);
 
141
    return false;
153
142
  SFXSize=0;
154
143
  
155
144
  RARFORMAT Type;
157
146
  {
158
147
    Format=Type;
159
148
    if (Format==RARFMT14)
160
 
      Seek(0,SEEK_SET);
 
149
      Seek(Tell()-SIZEOF_MARKHEAD3,SEEK_SET);
161
150
  }
162
151
  else
163
152
  {
185
174
  }
186
175
  if (Format==RARFMT_FUTURE)
187
176
  {
188
 
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
189
 
    Log(FileName,St(MNewRarFormat));
190
 
#endif
 
177
    uiMsg(UIERROR_NEWRARFORMAT,FileName);
191
178
    return false;
192
179
  }
193
180
  if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
200
187
  else
201
188
    MarkHead.HeadSize=SIZEOF_MARKHEAD3;
202
189
 
 
190
#ifdef RARDLL
 
191
  // If callback function is not set, we cannot get the password,
 
192
  // so we skip the initial header processing for encrypted header archive.
 
193
  // It leads to skipped archive comment, but the rest of archive data
 
194
  // is processed correctly.
 
195
  if (Cmd->Callback==NULL)
 
196
    SilentOpen=true;
 
197
#endif
 
198
 
203
199
  // Skip the archive encryption header if any and read the main header.
204
 
  while (ReadHeader()!=0 && GetHeaderType()!=HEAD_MAIN)
 
200
  while (ReadHeader()!=0)
 
201
  {
 
202
    HEADER_TYPE Type=GetHeaderType();
 
203
    // In RAR 5.0 we need to quit after reading HEAD_CRYPT if we wish to
 
204
    // avoid the password prompt.
 
205
    if (Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT)
 
206
      break;
205
207
    SeekToNext();
 
208
  }
206
209
 
207
210
  // This check allows to make RS based recovery even if password is incorrect.
208
211
  // But we should not do it for EnableBroken or we'll get 'not RAR archive'
211
214
    return false;
212
215
 
213
216
  SeekToNext();
214
 
  if (BrokenHeader)
 
217
  if (BrokenHeader) // Main archive header is corrupt.
215
218
  {
216
 
#ifndef SHELL_EXT
217
 
    Log(FileName,St(MMainHeaderBroken));
218
 
#endif
 
219
    uiMsg(UIERROR_MHEADERBROKEN,FileName);
219
220
    if (!EnableBroken)
220
221
      return false;
221
222
  }
222
223
 
223
 
/*
224
 
  if (MainHead.EncryptVer>VER_UNPACK)
225
 
  {
226
 
#ifdef RARDLL
227
 
    Cmd->DllError=ERAR_UNKNOWN_FORMAT;
228
 
#else
229
 
    ErrHandler.SetErrorCode(RARX_WARNING);
230
 
  #if !defined(SILENT) && !defined(SFX_MODULE)
231
 
      Log(FileName,St(MUnknownMeth),FileName);
232
 
      Log(FileName,St(MVerRequired),MainHead.EncryptVer/10,MainHead.EncryptVer%10);
233
 
  #endif
234
 
#endif
235
 
    return(false);
236
 
  }
237
 
*/
238
 
 
239
 
#ifdef RARDLL
240
 
  // If callback function is not set, we cannot get the password,
241
 
  // so we skip the initial header processing for encrypted header archive.
242
 
  // It leads to skipped archive comment, but the rest of archive data
243
 
  // is processed correctly.
244
 
  if (Cmd->Callback==NULL)
245
 
    SilentOpen=true;
246
 
#endif
247
 
 
248
224
  MainComment=MainHead.CommentInHeader;
249
225
 
250
 
#ifdef USE_QOPEN
251
 
  if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
252
 
  {
253
 
    QOpen.Init(this,false);
254
 
    QOpen.Load(MainHead.QOpenOffset);
255
 
  }
256
 
#endif
257
 
 
258
226
  // If we process non-encrypted archive or can request a password,
259
227
  // we set 'first volume' flag based on file attributes below.
260
228
  // It is necessary for RAR 2.x archives, which did not have 'first volume'
261
 
  // flag in main header.
 
229
  // flag in main header. Also for all RAR formats we need to scan until
 
230
  // first file header to set "comment" flag when reading service header.
 
231
  // Unless we are in silent mode, we need to know about presence of comment
 
232
  // immediately after IsArchive call.
262
233
  if (!SilentOpen || !Encrypted)
263
234
  {
264
235
    SaveFilePos SavePos(*this);
265
236
    int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
 
237
    HEADER_TYPE SaveCurHeaderType=CurHeaderType;
266
238
 
267
239
    while (ReadHeader()!=0)
268
240
    {
269
241
      HEADER_TYPE HeaderType=GetHeaderType();
270
242
      if (HeaderType==HEAD_SERVICE)
271
 
      {
272
 
        if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
273
 
          MainComment=true;
274
 
        FirstVolume=!SubHead.SplitBefore;
275
 
      }
 
243
        FirstVolume=Volume && !SubHead.SplitBefore;
276
244
      else
277
 
      {
278
 
        FirstVolume=HeaderType==HEAD_FILE && !FileHead.SplitBefore;
279
 
        break;
280
 
      }
 
245
        if (HeaderType==HEAD_FILE)
 
246
        {
 
247
          FirstVolume=Volume && !FileHead.SplitBefore;
 
248
          break;
 
249
        }
281
250
      SeekToNext();
282
251
    }
283
252
    CurBlockPos=SaveCurBlockPos;
284
253
    NextBlockPos=SaveNextBlockPos;
 
254
    CurHeaderType=SaveCurHeaderType;
285
255
  }
286
256
  if (!Volume || FirstVolume)
287
257
    wcscpy(FirstVolumeName,FileName);
320
290
 
321
291
 
322
292
#ifdef USE_QOPEN
 
293
bool Archive::Open(const wchar *Name,uint Mode)
 
294
{
 
295
  // Important if we reuse Archive object and it has virtual QOpen
 
296
  // file position not matching real. For example, for 'l -v volname'.
 
297
  QOpen.Unload();
 
298
 
 
299
  return File::Open(Name,Mode);
 
300
}
 
301
 
 
302
 
323
303
int Archive::Read(void *Data,size_t Size)
324
304
{
325
305
  size_t Result;