155 lines
3.9 KiB
C++
155 lines
3.9 KiB
C++
|
|
|
|
|
|
#ifndef SFX_MODULE
|
|
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) ||
|
|
Arc.StreamHead.StreamName[0]!=':')
|
|
{
|
|
#ifndef SILENT
|
|
Log(Arc.FileName,St(MStreamBroken),FileName);
|
|
#endif
|
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
|
return;
|
|
}
|
|
|
|
ConvertPath((char *)Arc.StreamHead.StreamName+1,(char *)Arc.StreamHead.StreamName+1);
|
|
|
|
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);
|
|
}
|
|
#endif
|
|
|
|
|
|
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];
|
|
size_t DestSize=Arc.SubHead.SubData.Size()/2;
|
|
|
|
if (strlenw(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);
|
|
}
|