#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 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); }