bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command) { RAROptions *Cmd=Arc.GetRAROptions(); int HeaderType=Arc.GetHeaderType(); FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd; bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) && (hd->Flags & LHD_SPLIT_AFTER)!=0; if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 && hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC) { Log(Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName); } int64 PosBeforeClose=Arc.Tell(); if (DataIO!=NULL) DataIO->ProcessedArcSize+=Arc.FileLength(); Arc.Close(); char NextName[NM]; wchar NextNameW[NM]; strcpy(NextName,Arc.FileName); wcscpy(NextNameW,Arc.FileNameW); NextVolumeName(NextName,NextNameW,ASIZE(NextName),(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat); #if !defined(SFX_MODULE) && !defined(RARDLL) bool RecoveryDone=false; #endif bool FailedOpen=false,OldSchemeTested=false; #if !defined(GUI) && !defined(SILENT) // In -vp mode we force the pause before next volume even if it is present // and even if we are on the hard disk. It is important when user does not // want to process partially downloaded volumes preliminary. if (Cmd->VolumePause && !AskNextVol(NextName,NextNameW)) FailedOpen=true; #endif if (!FailedOpen) while (!Arc.Open(NextName,NextNameW,0)) { // We need to open a new volume which size was not calculated // in total size before, so we cannot calculate the total progress // anymore. Let's reset the total size to zero and stop // the total progress. if (DataIO!=NULL) DataIO->TotalArcSize=0; if (!OldSchemeTested) { // Checking for new style volumes renamed by user to old style // name format. Some users did it for unknown reason. char AltNextName[NM]; wchar AltNextNameW[NM]; strcpy(AltNextName,Arc.FileName); wcscpy(AltNextNameW,Arc.FileNameW); NextVolumeName(AltNextName,AltNextNameW,ASIZE(AltNextName),true); OldSchemeTested=true; if (Arc.Open(AltNextName,AltNextNameW,0)) { strcpy(NextName,AltNextName); wcscpy(NextNameW,AltNextNameW); break; } } #ifdef RARDLL bool DllVolChanged=false; if (Cmd->Callback!=NULL) { GetWideName(NextName,NextNameW,NextNameW,ASIZE(NextNameW)); char CurName[ASIZE(NextName)]; strcpy(CurName,NextName); wchar CurNameW[ASIZE(NextNameW)]; wcscpy(CurNameW,NextNameW); if (Cmd->Callback(UCM_CHANGEVOLUMEW,Cmd->UserData,(LPARAM)NextNameW,RAR_VOL_ASK)!=-1 && wcscmp(CurNameW,NextNameW)!=0) { *NextName=0; DllVolChanged=true; } else if (Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LPARAM)NextName,RAR_VOL_ASK)!=-1 && strcmp(CurName,NextName)!=0) { *NextNameW=0; DllVolChanged=true; } } if (!DllVolChanged && Cmd->ChangeVolProc!=NULL) { // Here we preserve ESP value. It is necessary for those developers, // who still define ChangeVolProc callback as "C" type function, // even though in year 2001 we announced in unrar.dll whatsnew.txt // that it will be PASCAL type (for compatibility with Visual Basic). #if defined(_MSC_VER) #ifndef _WIN_64 __asm mov ebx,esp #endif #elif defined(_WIN_ALL) && defined(__BORLANDC__) _EBX=_ESP; #endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK); // Restore ESP after ChangeVolProc with wrongly defined calling // convention broken it. #if defined(_MSC_VER) #ifndef _WIN_64 __asm mov esp,ebx #endif #elif defined(_WIN_ALL) && defined(__BORLANDC__) _ESP=_EBX; #endif if (RetCode!=0) { *NextNameW=0; DllVolChanged=true; } } if (!DllVolChanged) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } #else // !RARDLL #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (!RecoveryDone) { RecVolumes RecVol; RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true); RecoveryDone=true; continue; } #endif #ifndef GUI if (!Cmd->VolumePause && !IsRemovable(NextName)) { FailedOpen=true; break; } #endif #ifndef SILENT if (Cmd->AllYes || !AskNextVol(NextName,NextNameW)) #endif { FailedOpen=true; break; } #endif // RARDLL } if (FailedOpen) { #if !defined(SILENT) && !defined(_WIN_CE) Log(Arc.FileName,St(MAbsNextVol),NextName); #endif Arc.Open(Arc.FileName,Arc.FileNameW,0); Arc.Seek(PosBeforeClose,SEEK_SET); return(false); } Arc.CheckArc(true); #ifdef RARDLL if (Cmd->Callback!=NULL) { GetWideName(NextName,NextNameW,NextNameW,ASIZE(NextNameW)); if (Cmd->Callback(UCM_CHANGEVOLUMEW,Cmd->UserData,(LPARAM)NextNameW,RAR_VOL_NOTIFY)==-1) return(false); if (Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LPARAM)NextName,RAR_VOL_NOTIFY)==-1) return(false); } if (Cmd->ChangeVolProc!=NULL) { #if defined(_WIN_ALL) && !defined(_MSC_VER) && !defined(__MINGW32__) _EBX=_ESP; #endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_NOTIFY); #if defined(_WIN_ALL) && !defined(_MSC_VER) && !defined(__MINGW32__) _ESP=_EBX; #endif if (RetCode==0) return(false); } #endif if (Command=='T' || Command=='X' || Command=='E') mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName); if (SplitHeader) Arc.SearchBlock(HeaderType); else Arc.ReadHeader(); if (Arc.GetHeaderType()==FILE_HEAD) { Arc.ConvertAttributes(); Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); } #ifndef GUI if (ShowFileName) { char OutName[NM]; IntToExt(Arc.NewLhd.FileName,OutName); #ifdef UNICODE_SUPPORTED bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled(); if (WideName) { wchar NameW[NM]; ConvertPath(Arc.NewLhd.FileNameW,NameW); char Name[NM]; if (WideToChar(NameW,Name) && IsNameUsable(Name)) strcpy(OutName,Name); } #endif mprintf(St(MExtrPoints),OutName); if (!Cmd->DisablePercentage) mprintf(" "); } #endif if (DataIO!=NULL) { if (HeaderType==ENDARC_HEAD) DataIO->UnpVolume=false; else { DataIO->UnpVolume=(hd->Flags & LHD_SPLIT_AFTER)!=0; DataIO->SetPackedSizeToRead(hd->FullPackSize); } #ifdef SFX_MODULE DataIO->UnpArcSize=Arc.FileLength(); #endif // Reset the size of packed data read from current volume. It is used // to display the total progress and preceding volumes are already // compensated with ProcessedArcSize, so we need to reset this variable. DataIO->CurUnpRead=0; DataIO->PackedCRC=0xffffffff; // DataIO->SetFiles(&Arc,NULL); } return(true); }
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command) { RAROptions *Cmd=Arc.GetRAROptions(); int HeaderType=Arc.GetHeaderType(); FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd; bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) && (hd->Flags & LHD_SPLIT_AFTER)!=0; if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 && hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC) { Log(Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName); } Int64 PosBeforeClose=Arc.Tell(); Arc.Close(); char NextName[NM]; strcpy(NextName,Arc.FileName); NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat); #if !defined(SFX_MODULE) && !defined(RARDLL) bool RecoveryDone=false; #endif bool FailedOpen=false,OldSchemeTested=false; while (!Arc.Open(NextName)) { if (!OldSchemeTested) { char AltNextName[NM]; strcpy(AltNextName,Arc.FileName); NextVolumeName(AltNextName,true); OldSchemeTested=true; if (Arc.Open(AltNextName)) { strcpy(NextName,AltNextName); break; } } #ifdef RARDLL if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL || Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } if (Cmd->ChangeVolProc!=NULL) { //#ifdef _WIN_32 // _EBX=_ESP; //#endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK); //#ifdef _WIN_32 // _ESP=_EBX; //#endif if (RetCode==0) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } } #else #if !defined(SFX_MODULE) //&& !defined(_WIN_CE) if (!RecoveryDone) { RecVolumes RecVol; RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true); RecoveryDone=true; continue; } #endif #ifndef GUI if (!Cmd->VolumePause && !IsRemovable(NextName)) { Log(Arc.FileName,St(MAbsNextVol),NextName); FailedOpen=true; break; } #endif #ifndef SILENT if (Cmd->AllYes || !AskNextVol(NextName)) #endif { FailedOpen=true; break; } #endif } if (FailedOpen) { Arc.Open(Arc.FileName,Arc.FileNameW); Arc.Seek(PosBeforeClose,SEEK_SET); return(false); } Arc.CheckArc(true); #ifdef RARDLL if (Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_NOTIFY)==-1) return(false); if (Cmd->ChangeVolProc!=NULL) { //#ifdef _WIN_32 // _EBX=_ESP; //#endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_NOTIFY); //#ifdef _WIN_32 // _ESP=_EBX; //#endif if (RetCode==0) return(false); } #endif if (Command=='T' || Command=='X' || Command=='E') mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName); if (SplitHeader) Arc.SearchBlock(HeaderType); else Arc.ReadHeader(); if (Arc.GetHeaderType()==FILE_HEAD) { Arc.ConvertAttributes(); Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); } #ifndef GUI if (ShowFileName) { mprintf(St(MExtrPoints),IntNameToExt(Arc.NewLhd.FileName)); if (!Cmd->DisablePercentage) mprintf(" "); } #endif if (DataIO!=NULL) { if (HeaderType==ENDARC_HEAD) DataIO->UnpVolume=false; else { DataIO->UnpVolume=(hd->Flags & LHD_SPLIT_AFTER); DataIO->SetPackedSizeToRead(hd->FullPackSize); } #ifdef SFX_MODULE DataIO->UnpArcSize=Arc.FileLength(); DataIO->CurUnpRead=0; #endif DataIO->PackedCRC=0xffffffff; // DataIO->SetFiles(&Arc,NULL); } return(true); }
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,wchar Command) { RAROptions *Cmd=Arc.GetRAROptions(); HEADER_TYPE HeaderType=Arc.GetHeaderType(); FileHeader *hd=HeaderType==HEAD_SERVICE ? &Arc.SubHead:&Arc.FileHead; bool SplitHeader=(HeaderType==HEAD_FILE || HeaderType==HEAD_SERVICE) && hd->SplitAfter; if (DataIO!=NULL && SplitHeader) { bool PackedHashPresent=Arc.Format==RARFMT50 || hd->UnpVer>=20 && hd->FileHash.CRC32!=0xffffffff; if (PackedHashPresent && !DataIO->PackedDataHash.Cmp(&hd->FileHash,hd->UseHashKey ? hd->HashKey:NULL)) uiMsg(UIERROR_CHECKSUMPACKED, Arc.FileName, hd->FileName); } int64 PosBeforeClose=Arc.Tell(); if (DataIO!=NULL) DataIO->ProcessedArcSize+=Arc.FileLength(); Arc.Close(); wchar NextName[NM]; wcscpy(NextName,Arc.FileName); NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering); #if !defined(SFX_MODULE) && !defined(RARDLL) bool RecoveryDone=false; #endif bool FailedOpen=false,OldSchemeTested=false; #if !defined(GUI) && !defined(SILENT) // In -vp mode we force the pause before next volume even if it is present // and even if we are on the hard disk. It is important when user does not // want to process partially downloaded volumes preliminary. if (Cmd->VolumePause && !uiAskNextVolume(NextName,ASIZE(NextName))) FailedOpen=true; #endif uint OpenMode = Cmd->OpenShared ? FMF_OPENSHARED : 0; if (!FailedOpen) while (!Arc.Open(NextName,OpenMode)) { // We need to open a new volume which size was not calculated // in total size before, so we cannot calculate the total progress // anymore. Let's reset the total size to zero and stop // the total progress. if (DataIO!=NULL) DataIO->TotalArcSize=0; if (!OldSchemeTested) { // Checking for new style volumes renamed by user to old style // name format. Some users did it for unknown reason. wchar AltNextName[NM]; wcscpy(AltNextName,Arc.FileName); NextVolumeName(AltNextName,ASIZE(AltNextName),true); OldSchemeTested=true; if (Arc.Open(AltNextName,OpenMode)) { wcscpy(NextName,AltNextName); break; } } #ifdef RARDLL if (!DllVolChange(Cmd,NextName,ASIZE(NextName))) { FailedOpen=true; break; } #else // !RARDLL #ifndef SFX_MODULE if (!RecoveryDone) { RecVolumesRestore(Cmd,Arc.FileName,true); RecoveryDone=true; continue; } #endif #ifndef GUI if (!Cmd->VolumePause && !IsRemovable(NextName)) { FailedOpen=true; break; } #endif #ifndef SILENT if (Cmd->AllYes || !uiAskNextVolume(NextName,ASIZE(NextName))) #endif { FailedOpen=true; break; } #endif // RARDLL } if (FailedOpen) { uiMsg(UIERROR_MISSINGVOL,NextName); Arc.Open(Arc.FileName,OpenMode); Arc.Seek(PosBeforeClose,SEEK_SET); return false; } if (Command=='T' || Command=='X' || Command=='E') mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName); Arc.CheckArc(true); #ifdef RARDLL if (!DllVolNotify(Cmd,NextName)) return false; #endif if (SplitHeader) Arc.SearchBlock(HeaderType); else Arc.ReadHeader(); if (Arc.GetHeaderType()==HEAD_FILE) { Arc.ConvertAttributes(); Arc.Seek(Arc.NextBlockPos-Arc.FileHead.PackSize,SEEK_SET); } #ifndef GUI if (ShowFileName) { mprintf(St(MExtrPoints),Arc.FileHead.FileName); if (!Cmd->DisablePercentage) mprintf(L" "); } #endif if (DataIO!=NULL) { if (HeaderType==HEAD_ENDARC) DataIO->UnpVolume=false; else { DataIO->UnpVolume=hd->SplitAfter; DataIO->SetPackedSizeToRead(hd->PackSize); } #ifdef SFX_MODULE DataIO->UnpArcSize=Arc.FileLength(); #endif // Reset the size of packed data read from current volume. It is used // to display the total progress and preceding volumes are already // compensated with ProcessedArcSize, so we need to reset this variable. DataIO->CurUnpRead=0; DataIO->PackedDataHash.Init(hd->FileHash.Type,Cmd->Threads); } return true; }
bool QTBuilder::build_eqg(const char *shortname) { // char bufm[96]; char bufs[96]; Archive *archive; FileLoader *fileloader; Zone_Model *zm; sprintf(bufs, "%s.eqg", shortname); archive = new PFSLoader(); FILE *fff = fopen(bufs, "rb"); if(fff == NULL) { printf("Failed to open '%s'\n", bufs); return(false); } if(archive->Open(fff) == 0) { printf("Unable to open eqg file '%s'.\n", bufs); return(false); } fileloader = new ZonLoader(); if(fileloader->Open(NULL, (char *) shortname, archive) == 0) { printf("Error reading ZON from %s\n", bufs); return(false); } zm = fileloader->model_data.zone_model; long i; VERTEX v1, v2, v3; for(i = 0; i < zm->poly_count; ++i) { #ifdef INVERSEXY v1.y = zm->verts[zm->polys[i]->v1]->x; v1.x = zm->verts[zm->polys[i]->v1]->y; #else v1.x = zm->verts[zm->polys[i]->v1]->x; v1.y = zm->verts[zm->polys[i]->v1]->y; #endif v1.z = zm->verts[zm->polys[i]->v1]->z; #ifdef INVERSEXY v2.y = zm->verts[zm->polys[i]->v2]->x; v2.x = zm->verts[zm->polys[i]->v2]->y; #else v2.x = zm->verts[zm->polys[i]->v2]->x; v2.y = zm->verts[zm->polys[i]->v2]->y; #endif v2.z = zm->verts[zm->polys[i]->v2]->z; #ifdef INVERSEXY v3.y = zm->verts[zm->polys[i]->v3]->x; v3.x = zm->verts[zm->polys[i]->v3]->y; #else v3.x = zm->verts[zm->polys[i]->v3]->x; v3.y = zm->verts[zm->polys[i]->v3]->y; #endif v3.z = zm->verts[zm->polys[i]->v3]->z; AddFace(v1, v2, v3); } printf(" There are %lu vertices and %u faces.\n", _FaceList.size()*3, _FaceList.size()); unsigned long r; // vertexCount = _VertexList.size(); faceCount = _FaceList.size(); /* vertexBlock = new VERTEX[vertexCount]; //im not going to assume I know vectors are stored in contiguous blocks for(r = 0; r < vertexCount; r++) { vertexBlock[r] = _VertexList[r]; }*/ faceBlock = new FACE[faceCount]; //im not going to assume I know vectors are stored in contiguous blocks for(r = 0; r < faceCount; r++) { faceBlock[r] = _FaceList[r]; } //build quad tree... prolly much slower than it needs to be. float minx, miny, maxx, maxy; minx = 1e12; miny = 1e12; maxx = -1e12; maxy = -1e12; //find our limits. for(r = 0; r < faceCount; r++) { //a bit of lazyness going on here... { VERTEX &v = faceBlock[r].a; if(v.x > maxx) maxx = v.x; if(v.x < minx) minx = v.x; if(v.y > maxy) maxy = v.y; if(v.y < miny) miny = v.y; } { VERTEX &v = faceBlock[r].b; if(v.x > maxx) maxx = v.x; if(v.x < minx) minx = v.x; if(v.y > maxy) maxy = v.y; if(v.y < miny) miny = v.y; } { VERTEX &v = faceBlock[r].c; if(v.x > maxx) maxx = v.x; if(v.x < minx) minx = v.x; if(v.y > maxy) maxy = v.y; if(v.y < miny) miny = v.y; } } printf(" Bounding box: %.2f < x < %.2f, %.2f < y < %.2f\n", minx, maxx, miny, maxy); printf("World file loaded.\n"); printf("Building quadtree.\n"); _root = new QTNode(this, minx, maxx, miny, maxy); if(_root == NULL) { printf("Unable to allocate new QTNode.\n"); return(false); } //build our initial set of faces... all of them: FACE *faceptr = faceBlock; _root->faces.resize(faceCount); for(r = 0; r < faceCount; r++) { _root->faces[r].face = faceptr; _root->faces[r].index = r; faceptr++; } /* _root->faces.resize(faceCount); for(r = 0; r < faceCount; r++) { _root->faces[r].face = &faceBlock[r]; //this is kinda bad, we dont own this //memory, so we shouldent be taking addrs... _root->faces[r].index = r; }*/ _root->divideYourself(0); printf("Done building quad tree...\n"); #ifdef COUNT_MACTHES fprintf(stderr, "Match counters: %lu easy in, %lu easy out, %lu hard in, %lu hard out.\n", gEasyMatches, gEasyExcludes, gHardMatches, gHardExcludes); #endif return(true); }
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command) { RAROptions *Cmd=Arc.GetRAROptions(); int HeaderType=Arc.GetHeaderType(); FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd; bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) && (hd->Flags & LHD_SPLIT_AFTER)!=0; if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 && hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC) { Log(Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName); } Int64 PosBeforeClose=Arc.Tell(); Arc.Close(); char NextName[NM]; strcpy(NextName,Arc.FileName); NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat); #if !defined(SFX_MODULE) && !defined(RARDLL) bool RecoveryDone=false; #endif bool FailedOpen=false,OldSchemeTested=false; while (!Arc.Open(NextName)) { if (!OldSchemeTested) { char AltNextName[NM]; strcpy(AltNextName,Arc.FileName); NextVolumeName(AltNextName,true); OldSchemeTested=true; if (Arc.Open(AltNextName)) { strcpy(NextName,AltNextName); break; } } #ifdef RARDLL if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL || Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } if (Cmd->ChangeVolProc!=NULL) { #ifdef _WIN_32 __asm { mov EBX, ESP } #endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK); #ifdef _WIN_32 __asm { mov ESP, EBX } #endif if (RetCode==0) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } } #else #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (!RecoveryDone) { RecVolumes RecVol; RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true); RecoveryDone=true; continue; } #endif #ifndef GUI if (!Cmd->VolumePause && !IsRemovable(NextName)) { Log(Arc.FileName,St(MAbsNextVol),NextName); FailedOpen=true; break; } #endif #ifndef SILENT if (Cmd->AllYes || !AskNextVol(NextName)) #endif { FailedOpen=true; break; } #endif }
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command) { RAROptions *Cmd=Arc.GetRAROptions(); int HeaderType=Arc.GetHeaderType(); FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd; bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) && (hd->Flags & LHD_SPLIT_AFTER)!=0; if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 && hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC) { Log(Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName); } Int64 PosBeforeClose=Arc.Tell(); Arc.Close(); char NextName[NM]; wchar NextNameW[NM]; *NextNameW=0; strcpy(NextName,Arc.FileName); NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat); if (*Arc.FileNameW!=0) { // Copy incremented trailing low ASCII volume name part to Unicode name. // It is simpler than also implementing Unicode version of NextVolumeName. strcpyw(NextNameW,Arc.FileNameW); char *NumPtr=GetVolNumPart(NextName); // moving to first digit in volume number while (NumPtr>NextName && isdigit(*NumPtr) && isdigit(*(NumPtr-1))) NumPtr--; // also copy the first character before volume number, // because it can be changed when going from .r99 to .s00 if (NumPtr>NextName) NumPtr--; int CharsToCopy=strlen(NextName)-(NumPtr-NextName); int DestPos=strlenw(NextNameW)-CharsToCopy; if (DestPos>0) { CharToWide(NumPtr,NextNameW+DestPos,ASIZE(NextNameW)-DestPos-1); NextNameW[ASIZE(NextNameW)-1]=0; } } #if !defined(SFX_MODULE) && !defined(RARDLL) bool RecoveryDone=false; #endif bool FailedOpen=false,OldSchemeTested=false; while (!Arc.Open(NextName,NextNameW)) { if (!OldSchemeTested) { char AltNextName[NM]; strcpy(AltNextName,Arc.FileName); NextVolumeName(AltNextName,true); OldSchemeTested=true; if (Arc.Open(AltNextName)) { strcpy(NextName,AltNextName); *NextNameW=0; break; } } #ifdef RARDLL if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL || Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } if (Cmd->ChangeVolProc!=NULL) { #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _EBX=_ESP; #endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK); #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _ESP=_EBX; #endif if (RetCode==0) { Cmd->DllError=ERAR_EOPEN; FailedOpen=true; break; } } #else // RARDLL #if !defined(SFX_MODULE) && !defined(_WIN_CE) if (!RecoveryDone) { RecVolumes RecVol; RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true); RecoveryDone=true; continue; } #endif #ifndef GUI if (!Cmd->VolumePause && !IsRemovable(NextName)) { FailedOpen=true; break; } #endif #ifndef SILENT if (Cmd->AllYes || !AskNextVol(NextName)) #endif { FailedOpen=true; break; } #endif // RARDLL *NextNameW=0; } if (FailedOpen) { #if !defined(SILENT) && !defined(_WIN_CE) Log(Arc.FileName,St(MAbsNextVol),NextName); #endif Arc.Open(Arc.FileName,Arc.FileNameW); Arc.Seek(PosBeforeClose,SEEK_SET); return(false); } Arc.CheckArc(true); #ifdef RARDLL if (Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_NOTIFY)==-1) return(false); if (Cmd->ChangeVolProc!=NULL) { #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _EBX=_ESP; #endif int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_NOTIFY); #if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__) _ESP=_EBX; #endif if (RetCode==0) return(false); } #endif if (Command=='T' || Command=='X' || Command=='E') mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName); if (SplitHeader) Arc.SearchBlock(HeaderType); else Arc.ReadHeader(); if (Arc.GetHeaderType()==FILE_HEAD) { Arc.ConvertAttributes(); Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); } #ifndef GUI if (ShowFileName) { char OutName[NM]; IntToExt(Arc.NewLhd.FileName,OutName); #ifdef UNICODE_SUPPORTED bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled(); if (WideName) { wchar NameW[NM]; ConvertPath(Arc.NewLhd.FileNameW,NameW); char Name[NM]; if (WideToChar(NameW,Name) && IsNameUsable(Name)) strcpy(OutName,Name); } #endif mprintf(St(MExtrPoints),OutName); if (!Cmd->DisablePercentage) mprintf(" "); } #endif if (DataIO!=NULL) { if (HeaderType==ENDARC_HEAD) DataIO->UnpVolume=false; else { DataIO->UnpVolume=(hd->Flags & LHD_SPLIT_AFTER); DataIO->SetPackedSizeToRead(hd->FullPackSize); } #ifdef SFX_MODULE DataIO->UnpArcSize=Arc.FileLength(); DataIO->CurUnpRead=0; #endif DataIO->PackedCRC=0xffffffff; // DataIO->SetFiles(&Arc,NULL); } return(true); }