BOOL C4UpdatePackage::Optimize(C4Group *pGroup, const char *strTarget) { // Open target group C4GroupEx TargetGrp; if (!TargetGrp.Open(strTarget)) return FALSE; // Both groups must be packed if (!pGroup->IsPacked() || !TargetGrp.IsPacked()) { TargetGrp.Close(FALSE); return FALSE; } // update children char ItemFileName[_MAX_PATH]; pGroup->ResetSearch(); while (pGroup->FindNextEntry("*", ItemFileName)) if (!SEqual(ItemFileName, C4CFN_UpdateCore) && !SEqual(ItemFileName, C4CFN_UpdateEntries)) Optimize(pGroup, &TargetGrp, ItemFileName); // set header if (TargetGrp.HeadIdentical(*pGroup, true)) TargetGrp.SetHead(*pGroup); // save TargetGrp.Close(FALSE); // okay return TRUE; }
BOOL C4UpdatePackage::Execute(C4Group *pGroup) { // search target C4GroupEx TargetGrp; char strTarget[_MAX_PATH]; SCopy(DestPath, strTarget, _MAX_PATH); char *p = strTarget, *lp = strTarget; while (p = strchr(p + 1, '\\')) { *p = 0; if (!*(p + 1)) break; if (!SEqual(lp, "..")) if (TargetGrp.Open(strTarget)) { // packed? bool fPacked = TargetGrp.IsPacked(); // maker check (someone might try to unpack directories w/o asking user) if (fPacked) if (!SEqual(TargetGrp.GetMaker(), pGroup->GetMaker())) return FALSE; // Close Group TargetGrp.Close(TRUE); if (fPacked) // Unpack C4Group_UnpackDirectory(strTarget); } else { // GrpUpdate -> file must exist if (GrpUpdate) return FALSE; // create dir CreateDirectory(strTarget, NULL); } *p = '\\'; lp = p + 1; } // try to open it if (!TargetGrp.Open(strTarget, !GrpUpdate)) return FALSE; // check if the update is allowed if (GrpUpdate) { // maker must match /*if(!SEqual(TargetGrp.GetMaker(), pGroup->GetMaker())) - now allowing updates from different makers return FALSE;*/ // check checksum uint32_t iCRC32; if (!C4Group_GetFileCRC(TargetGrp.GetFullName().getData(), &iCRC32)) return FALSE; int i = 0; for (; i < UpGrpCnt; i++) if (iCRC32 == GrpChks1[i]) break; if (i >= UpGrpCnt) return FALSE; } else { // only allow Extra.c4g-Updates if (!SEqual2(DestPath, "Extra.c4g")) return FALSE; } // update children char ItemFileName[_MAX_PATH]; pGroup->ResetSearch(); while (pGroup->FindNextEntry("*", ItemFileName)) if (!SEqual(ItemFileName, C4CFN_UpdateCore) && !SEqual(ItemFileName, C4CFN_UpdateEntries)) DoUpdate(pGroup, &TargetGrp, ItemFileName); // do GrpUpdate if (GrpUpdate) DoGrpUpdate(pGroup, &TargetGrp); // close the group TargetGrp.Close(FALSE); if (GrpUpdate) { // check the result uint32_t iResChks; if (!C4Group_GetFileCRC(strTarget, &iResChks)) return FALSE; if (iResChks != GrpChks2) { #ifdef UPDATE_DEBUG char *pData; int iSize; CStdFile MyFile; MyFile.Load(strTarget, (BYTE **)&pData, &iSize, 0, TRUE); MyFile.Create("DiesesDingIstMist.txt", FALSE); MyFile.Write(pData, iSize, FALSE); MyFile.Close(); #endif return FALSE; } } return TRUE; }