Beispiel #1
0
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;
}
Beispiel #2
0
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;
}