int 
T64Archive::getNumberOfItems()
{
	int noOfItems;

	// Get number of files from the file header...
    noOfItems = LO_HI(data[0x24], data[0x25]);

	if (noOfItems == 0) {

        // Note: Some archives don't store this value properly.
		// In this case, we can determine the number of files
		// by iterating through the directory area...
		while (directoryItemIsPresent(noOfItems))
			noOfItems++;
	}

	return noOfItems;
}
Beispiel #2
0
bool
T64File::repair()
{
    unsigned i, n;
    uint16_t noOfItems = numberOfItems();

    //
    // 1. Repair number of items, if this value is zero
    //
    
    if (noOfItems == 0) {

        while (directoryItemIsPresent(noOfItems))
            noOfItems++;

        uint16_t noOfItemsStatedInHeader = numberOfItems();
        if (noOfItems != noOfItemsStatedInHeader) {
        
            debug(1, "Repairing corrupted T64 archive: Changing number of items from %d to %d.\n",
                  noOfItemsStatedInHeader, noOfItems);
        
            data[0x24] = LO_BYTE(noOfItems);
            data[0x25] = HI_BYTE(noOfItems);
            
        }
        assert(noOfItems == numberOfItems());
    }
    
    for (i = 0; i < noOfItems; i++) {

        //
        // 2. Check relative offset information for each item
        //

        // Compute start address in file
        n = 0x48 + (i * 0x20);
        uint16_t startAddrInContainer = LO_LO_HI_HI(data[n], data[n+1], data[n+2], data[n+3]);

        if (startAddrInContainer >= size) {
            warn("T64 archive is corrupt (offset mismatch). Sorry, can't repair.\n");
            return false;
        }
    
        //
        // 3. Check for file end address mismatches (as created by CONVC64)
        //
        
        // Compute start address in memory
        n = 0x42 + (i * 0x20);
        uint16_t startAddrInMemory = LO_HI(data[n], data[n+1]);
    
        // Compute end address in memory
        n = 0x44 + (i * 0x20);
        uint16_t endAddrInMemory = LO_HI(data[n], data[n+1]);
    
        if (endAddrInMemory == 0xC3C6) {

            // Let's assume that the rest of the file data belongs to this file ...
            uint16_t fixedEndAddrInMemory = startAddrInMemory + (size - startAddrInContainer);

            debug(1, "Repairing corrupted T64 archive: Changing end address of item %d from %04X to %04X.\n",
                  i, endAddrInMemory, fixedEndAddrInMemory);

            data[n] = LO_BYTE(fixedEndAddrInMemory);
            data[n+1] = HI_BYTE(fixedEndAddrInMemory);
        }
    }
    
    return 1; // Archive repaired successfully
}