Beispiel #1
0
GraphicComp* ImportCmd::PPM_Image (const char* filename) {
    GraphicComp* comp = nil;
    FILE* file = fopen(filename, "r");
    boolean compressed;
    file = CheckCompression(file, filename, compressed);

    if (file != nil) {
        char line[1000];
        do {
            fgets(line, 1000, file);
        } while (strcmp(line, "gsave\n") != 0);

        fgets(line, 1000, file);                    // translate
        fgets(line, 1000, file);                    // scale
        fgets(line, 1000, file);                    // scale
        fgets(line, 1000, file);                    // sizes
        int w, h, d;
        sscanf(line, "%d %d %d", &w, &h, &d);
        fgets(line, 1000, file);                    // [ ... ]
        fgets(line, 1000, file);                    // { ... }
        fgets(line, 1000, file);                    // false 3
        fgets(line, 1000, file);                    // colorimage

        Raster* raster = new Raster(w, h);

        for (int row = h - 1; row >= 0; --row) {
            for (int column = 0; column < w; ++column) {
                int red = gethex(file);
                int green = gethex(file);
                int blue = gethex(file);
                raster->poke(
                    column, row,
                    float(red)/0xff, float(green)/0xff, float(blue)/0xff, 1.0
                );
            }
        }
        raster->flush();
        comp = new RasterComp(new RasterRect(raster), filename);
    }
    
    if (compressed) {
        pclose(file);

    } else {
        fclose(file);
    }
    return comp;
}
Beispiel #2
0
static const char* ReadCreator (const char* filename) {
    char* buf = nil;
    FILE* file = fopen(filename, "r");
    
    if (file != nil) {
        bool compressed;
        static char creator[CHARBUFSIZE];
        char line[CHARBUFSIZE];
        
        file = CheckCompression(file, filename, compressed);

        if (!file) {
            return NULL;
        }

        if (fgets(line, CHARBUFSIZE, file) != NULL) {

            /* Two-byte magic numbers */

            switch(*((unsigned short *)line)) {
            case TIFF1_MAGIC_NUM:
            case TIFF2_MAGIC_NUM:
                return ("TIFF");
            case SUN_MAGIC_NUM:
                return ("SUN");
            }

            /* One-byte Magic numbers */

            switch (line[0]) {
            case BM_MAGIC_NUM:
                return ("BM");
            case PBM_MAGIC_NUM:
                return ("PBM");
            case ATK_MAGIC_NUM:
                return ("ATK");
            case MP_MAGIC_NUM:
                return ("MP");
            case X11_MAGIC_NUM:
                return ("X11");
            case PCX_MAGIC_NUM:
                return ("PCX");
            case IFF_MAGIC_NUM:
                return ("IFF");
            case GIF_MAGIC_NUM:
                return ("GIF");
            case RLE_MAGIC_NUM:
                return ("RLE");
            }

        } else {
            return NULL;
        }

        do {
            if (sscanf(line, "%%%%Creator: %s", creator)) {
                buf = creator;
                break;
                
            } else if (strcmp(line, "%%EndComments\n") == 0) {
                break;
            }
        } while (fgets(line, CHARBUFSIZE, file) != NULL);

        if (compressed) {
            pclose(file);

        } else {
            fclose(file);
        }
    }
    return buf;
}
Beispiel #3
0
//
// save any information required to support calibration
//
static int Ar9300EepromSave()
{
    ar9300_eeprom_t *mptr;        // pointer to data
    int msize;
    unsigned char header[compression_header_length], cheader[compression_header_length], before[compression_header_length];
    char best[MOUTPUT];
    int osize;
    int it;
    ar9300_eeprom_t *dptr;
    int dsize;
    int first;
    int last;
    int ib;
    int bsize;
    int breference;
    int balgorithm;
    int offset[MVALUE],value[MVALUE];
    int overhead;
    ar9300_eeprom_t xptr;
    int nextaddress;
    int major, minor;
    int ccode,creference,cmajor,cminor,clength;
    unsigned short checksum;
    unsigned char csum[2];
    int error;
    int written;
	int ntry;
    unsigned char ones[compression_header_length]={0xff,0xff,0xff,0xff};
    int status;
	int calmem;
	int restored;
	int trysave;
    //
    // get a pointer to the current data structure
    //
    mptr=Ar9300EepromStructGet();
    msize=ar9300_eeprom_struct_size();

	calmem=SaveMemory;
	if(calmem==calibration_data_none)
	{
		calmem=ar9300_calibration_data_get(AH);
	}
	if(calmem==calibration_data_none)
	{
	    if(ar9300_eeprom_size(AH)>0)
		{
			calmem=calibration_data_eeprom;
		}
		else if(ar9300_calibration_data_read_flash(AH, 0x1000, header, 1)==AH_TRUE)
		{
			calmem=calibration_data_flash;
		}
		else
		{
			calmem=calibration_data_otp;
		}
	}

	 // Calculate Checksum
 	checksum=ar9300_compression_checksum((unsigned char*)mptr,msize);
	printf("checksum is %x\n",checksum);
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
//	ar9300_eeprom_t *eeprom_ptr;
//	eeprom_ptr=Ar9300EepromStructGet();
    ar9300_eeprom_template_swap();
    ar9300_swap_eeprom(mptr);
#endif
   
    // For AP with flash calibration data storage save structure uncompressed.
#ifdef MDK_AP
    if(calmem==calibration_data_flash)
    {
        int fd;
        int offset;
        // for(it=0;it<many;it++)
        //    printf("a = %x, data = %x \n",(address-it), buffer[it]);
        if((fd = open("/dev/caldata", O_RDWR)) < 0) {
            perror("Could not open flash\n");
            status = -1 ;
            goto return_status;
        }

        // First 0x1000 are reserved for ethernet mac address and other config writes.
        offset = 0x20000+instance*AR9300_EEPROM_SIZE+FLASH_BASE_CALDATA_OFFSET;  // Need for boards with more than one radio
        lseek(fd, offset, SEEK_SET);
        if (write(fd, mptr, msize) < 1) {
            perror("\nwrite\n");
            status = -2 ;
            goto return_status;
        }
		close(fd);

        status = msize ;
        goto return_status;
    }    
#endif
    
    //
    // try all of our compression schemes, 
    // starting with the assumption that uncompressed is best
    //
    balgorithm=_compress_none;
    breference= -1;
    bsize=msize;
	nextaddress= -1;
    //
	// restore the existing eeprom structure to a temporary buffer
	// because we need it later for several reasons. Returns 0
	// if a default template was loaded because there was no data in memory.
	// Return -1 on error. Otherwise returns the next available address.
	//
#ifdef USE_AQUILA_HAL
 	trysave=ar9300CalibrationDataGet(0);	
 	ar9300CalibrationDataSet(0,calmem);	
#else
	trysave=AH9300(AH)->calibration_data_try;	
	AH9300(AH)->calibration_data_try = calmem;	
#endif
	restored=ar9300_eeprom_restore_internal(AH, &xptr, msize);
	if(restored==0)
	{
		nextaddress= -1;
	}
	else
	{
		nextaddress=restored;
	}
	ar9300_calibration_data_set(AH,calmem);
#ifdef USE_AQUILA_HAL
	ar9300CalibrationDataSet(0,trysave);
#else
	AH9300(AH)->calibration_data_try = trysave;	
#endif
	//
	// do we over write or append
	// if overwrite, move the starting address to the top of the memory
	//
	if((Overwrite && ar9300_eeprom_volatile(AH)) || nextaddress<0)
	{ 
		if(SaveAddress==0)
		{
			nextaddress=ar9300_eeprom_base_address(AH);
		}
		else
		{
			nextaddress=SaveAddress;
		}
	}
    //
	// if compression is requested or if the uncompressed data won't fit
	//
	if(Compress || nextaddress-msize-compression_header_length-compression_checksum_length<=ar9300_eeprom_low_limit(AH))
	{
		//
		// try difference with each standard default structure
		//
		if(TemplateAllowedMany<=0)
		{
			for(it=0; it<ar9300_eeprom_struct_default_many(); it++)
			{
				dptr=ar9300_eeprom_struct_default(it);
				dsize=msize;
				if(dptr!=0 && dsize<MOUTPUT && dsize==msize)
				{
					CheckCompression((char *)mptr,msize,(char *)dptr,dptr->template_version,&balgorithm,&breference,&bsize,best,MOUTPUT);
				}
			}
		}
		else
		{
			for(it=0; it<TemplateAllowedMany; it++)
			{
				dptr=ar9300_eeprom_struct_default_find_by_id(TemplateAllowed[it]);
				dsize=msize;
				if(dptr!=0 && dsize<MOUTPUT && dsize==msize)
				{
					CheckCompression((char *)mptr,msize,(char *)dptr,dptr->template_version,&balgorithm,&breference,&bsize,best,MOUTPUT);
				}
			}
		}
		//
		// also try difference with existing eeprom if it was restored from memory
		//
		if((!(Overwrite && ar9300_eeprom_volatile(AH))) && restored>0 && xptr.eeprom_version==mptr->eeprom_version)
		{
			CheckCompression((char *)mptr,msize,(char *)&xptr,reference_current,&balgorithm,&breference,&bsize,best,MOUTPUT);
		}
	}
    //
    // if the uncompressed size is the smallest, might as well go with it
    //
    if(bsize>=msize)
    {
        balgorithm=_compress_none;
        breference= reference_current;
        bsize=msize;
        memcpy(best,mptr,msize);        // the uncompressed data
		//
		// if using OTP we have to find the first free spot.
		// if using eeprom, we can overwrite
		//
    }
    //
    // Now we know the best method and we have the data, so write it
    //
    ErrorPrint(EepromAlgorithm,balgorithm,breference,bsize,nextaddress);
    if(bsize>0 || restored==0)
    {
        written=0;
        osize=bsize;
		ntry=0;
        while(written==0 &&
			nextaddress-osize-compression_header_length-compression_checksum_length>ar9300_eeprom_low_limit(AH))
        {
			ntry++;
            if(ntry>3)
            {
                ErrorPrint(EepromTooMany);
                status = -2;
                goto return_status;
            }
            //
            // read the spot where we're going to write the header
			// this is so we can check on error if the chip managed to write anything at all
            //
            (void)ar9300_calibration_data_read_array(AH,nextaddress,(unsigned char*)before,compression_header_length);
            //
            // create and write header
            //
            major=NartVersionMajor();
            minor=NartVersionMinor();
            CompressionHeaderPack(header, balgorithm, breference, bsize, major, minor);
            error=CalibrationDataWriteAndVerify(nextaddress,header,compression_header_length);
            if(error==0)
			{
				//
				// write data
				//
				nextaddress-=compression_header_length;
				error=CalibrationDataWriteAndVerify(nextaddress,(unsigned char*)best,osize);
				nextaddress-=osize;
				if(error==0)
				{
					//
					// create and write checksum
					//
					checksum=ar9300_compression_checksum((unsigned char*)best,bsize);
                    csum[0]=checksum&0xff;
                    csum[1]=(checksum>>8)&0xff;
					error=CalibrationDataWriteAndVerify(nextaddress,csum,compression_checksum_length);
					nextaddress-=compression_checksum_length;
					if(error==0)
					{
						//
						// everything written successfully, so we're done
						//
						written=1;
					}
					else
					{
						 //
						 // and try again
						 //
					}
				}
				else
				{
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum)
{
	const std::string fn    = FileSystem::GetFilename(fullName);
	const std::string fpath = FileSystem::GetDirectory(fullName);
	const std::string lcfn  = StringToLower(fn);

	// Stat file
	struct stat info = {0};
	int statfailed = stat(fullName.c_str(), &info);

	// If stat fails, assume the archive is not broken nor cached
	if (!statfailed) {
		// Determine whether this archive has earlier be found to be broken
		std::map<std::string, BrokenArchive>::iterator bai = brokenArchives.find(lcfn);
		if (bai != brokenArchives.end()) {
			if ((unsigned)info.st_mtime == bai->second.modified && fpath == bai->second.path) {
				bai->second.updated = true;
				return;
			}
		}

		// Determine whether to rely on the cached info or not
		std::map<std::string, ArchiveInfo>::iterator aii = archiveInfos.find(lcfn);
		if (aii != archiveInfos.end()) {
			// This archive may have been obsoleted, do not process it if so
			if (!aii->second.replaced.empty()) {
				return;
			}

			if ((unsigned)info.st_mtime == aii->second.modified && fpath == aii->second.path) {
				// cache found update checksum if wanted
				aii->second.updated = true;
				if (doChecksum && (aii->second.checksum == 0)) {
					aii->second.checksum = GetCRC(fullName);
				}
				return;
			} else {
				if (aii->second.updated) {
					const std::string filename = aii->first;
					LOG_L(L_ERROR, "Found a \"%s\" already in \"%s\", ignoring.", fullName.c_str(), (aii->second.path + aii->second.origName).c_str());
					if (IsBaseContent(filename)) {
						throw user_error(std::string("duplicate base content detected:\n\t") + aii->second.path + std::string("\n\t") + fpath
							+ std::string("\nPlease fix your configuration/installation as this can cause desyncs!"));
					}
					return;
				}

				// If we are here, we could have invalid info in the cache
				// Force a reread if it is a directory archive (.sdd), as
				// st_mtime only reflects changes to the directory itself,
				// not the contents.
				archiveInfos.erase(aii);
			}
		}
	}

	boost::scoped_ptr<IArchive> ar(archiveLoader.OpenArchive(fullName));
	if (!ar || !ar->IsOpen()) {
		LOG_L(L_WARNING, "Unable to open archive: %s", fullName.c_str());

		// record it as broken, so we don't need to look inside everytime
		BrokenArchive& ba = brokenArchives[lcfn];
		ba.path = fpath;
		ba.modified = info.st_mtime;
		ba.updated = true;
		ba.problem = "Unable to open archive";
		return;
	}

	std::string error;
	std::string mapfile;

	const bool hasModinfo = ar->FileExists("modinfo.lua");
	const bool hasMapinfo = ar->FileExists("mapinfo.lua");


	ArchiveInfo ai;
	auto& ad = ai.archiveData;
	if (hasMapinfo) {
		ScanArchiveLua(ar.get(), "mapinfo.lua", ai, error);
		if (ad.GetMapFile().empty()) {
			LOG_L(L_WARNING, "%s: mapfile isn't set in mapinfo.lua, please set it for faster loading!", fullName.c_str());
			mapfile = SearchMapFile(ar.get(), error);
		}
	} else if (hasModinfo) {
		ScanArchiveLua(ar.get(), "modinfo.lua", ai, error);
	} else {
		mapfile = SearchMapFile(ar.get(), error);
	}
	CheckCompression(ar.get(), fullName, error);

	if (!error.empty()) {
		// for some reason, the archive is marked as broken
		LOG_L(L_WARNING, "Failed to scan %s (%s)", fullName.c_str(), error.c_str());

		// record it as broken, so we don't need to look inside everytime
		BrokenArchive& ba = brokenArchives[lcfn];
		ba.path = fpath;
		ba.modified = info.st_mtime;
		ba.updated = true;
		ba.problem = error;
		return;
	}

	if (hasMapinfo || !mapfile.empty()) {
		// it is a map
		if (ad.GetName().empty()) {
			// FIXME The name will never be empty, if version is set (see HACK in ArchiveData)
			ad.SetInfoItemValueString("name_pure", FileSystem::GetBasename(mapfile));
			ad.SetInfoItemValueString("name", FileSystem::GetBasename(mapfile));
		}
		if (ad.GetMapFile().empty()) {
			ad.SetInfoItemValueString("mapfile", mapfile);
		}

		AddDependency(ad.GetDependencies(), "Map Helper v1");
		ad.SetInfoItemValueInteger("modType", modtype::map);

		LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new map: %s", ad.GetNameVersioned().c_str());
	} else if (hasModinfo) {
		// it is a game
		if (ad.GetModType() == modtype::primary) {
			AddDependency(ad.GetDependencies(), "Spring content v1");
		}

		LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new game: %s", ad.GetNameVersioned().c_str());
	} else {
		// neither a map nor a mod: error
		error = "missing modinfo.lua/mapinfo.lua";
	}

	ai.path = fpath;
	ai.modified = info.st_mtime;
	ai.origName = fn;
	ai.updated = true;
	ai.checksum = (doChecksum) ? GetCRC(fullName) : 0;
	archiveInfos[lcfn] = ai;
}
//---------------------------------------------------------------------------
// Open an image store - this determines the type of the store and whether
// or not NT open functions are available and then decides the best way
// to open the target.
//
bool __fastcall TImageStore::Open(void)
{
    FGeometry.Bytes = (unsigned long long)0;
    FGeometry.BytesPerSector = (unsigned long long)0;

    switch (FType) {
    case isFile: {
        /// TODO handle Access var, createmode, shareMode
        int flags = O_NOCTTY |O_LARGEFILE;
        if (bWriteAccess) {
            flags |= O_WRONLY|O_CREAT|O_TRUNC;
        } else {
            flags |= O_RDONLY;
        }
        hHandle = open(FFileName.c_str(), flags);
        if (hHandle > 0) {
            if (!bWriteAccess) {
                //LONGLONG Pos;
                //Pos = lseek (hHandle, 0, SEEK_CUR);
                FGeometry.Bytes = lseek (hHandle, 0, SEEK_END);
                lseek (hHandle, 0, SEEK_SET);
                CheckCompression();
            } else
                FGeometry.Bytes = 0; //-1;
            FGeometry.BytesPerSector = 0;
            FGeometry.BytesPerCluster = 0;
        } else
            return false;
        break;
    }  // case isFile:

    case isDrive: {
        struct hd_geometry	geom;
        double			MBsize = 0;

        /// TODO handle Access var, createmode, shareMode
        int flags = O_NOCTTY | O_SYNC | O_LARGEFILE;
        if (bWriteAccess) {
            flags |= O_WRONLY;
        } else {
            flags |= O_RDONLY;
        }
        hHandle = open(FFileName.c_str(), flags);
        if (hHandle > 0) {

            //DeviceIoControl(hHandle, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &PartitionInfo, sizeof(PartitionInfo), &Dummy, NULL);
            //DeviceIoControl(hHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY	, NULL, 0, &DiskGeometry, sizeof(DiskGeometry), &Dummy, NULL);

            /* get C/H/S geometry and size of partition */
            if(ioctl(hHandle, HDIO_GETGEO, &geom) < 0)
                printf("HDIO_GETGEO ioctl failed");

            /* get size of block  */
            if(ioctl(hHandle, BLKSSZGET, &FGeometry.BytesPerSector) < 0)
                printf("BLKSSZGET ioctl failed");

            /* get size of the partition, chould match C*H*S */
            if(ioctl(hHandle, BLKGETSIZE, &FGeometry.NumbSectors) < 0)
                printf("BLKGETSIZE ioctl failed");

            // TODO
            FGeometry.Bytes = (unsigned long long)FGeometry.NumbSectors * (unsigned long long)FGeometry.BytesPerSector;

            MBsize = ( FGeometry.NumbSectors)/(1024 * 1024 / FGeometry.BytesPerSector);
#ifdef DEBUG_PARTSIZE
            printf("\n");
            if (MBsize > 1024)
                printf(" Geometry for %s, size = %.2f Gb\n", FFileName.c_str(), (float) (MBsize/1024));
            else
                printf(" Geometry for %s, size = %.2f Mb\n", FFileName.c_str(), (float) MBsize);
            printf("\t        Cylinders: %d\n", geom.cylinders);
            printf("\t            Heads: %d\n", geom.heads);
            printf("\t          Sectors: %d\n", geom.sectors);
            printf("\t    Total sectors: %lu\n", (long unsigned) FGeometry.NumbSectors);
            printf("\t     First sector: %lu\n", geom.start);
            printf("\t      Last sector: %lu\n", (long unsigned) (geom.start + FGeometry.NumbSectors - 1));
            printf("\n\n\n");
            printf("\t   BytesPerSector: %i\n",  FGeometry.BytesPerSector);
            printf("\t  PartitionLength: %i\n", (int)FGeometry.NumbSectors);
            printf("\t  Bytes: %llu\n", FGeometry.Bytes);

            printf("\n");
#endif

        } else
            return false;
        /// TODO enable check compression
        //CheckFileSystem();
        break;
    }  // case isDrive:

    default:
        // ERROR
        return false;
        break;
    }  // switch (Type)

    return true;
}  // bool __fastcall TImageStore::Open(void)
//---------------------------------------------------------------------------
// Open an image store - this determines the type of the store and whether
// or not NT open functions are available and then decides the best way
// to open the target.
//
bool __fastcall TImageStore::Open(void) {
    FGeometry.Bytes = (unsigned long long)0;
    FGeometry.BytesPerSector = (unsigned long long)0;
    bool bSuccess;

    switch (FType) {
    case isFile: {
        LARGE_INTEGER nnFileSize;

        DWORD ShareMode  = FILE_SHARE_READ;//(bWriteAccess?0:FILE_SHARE_READ);
        DWORD CreateMode = (bWriteAccess?CREATE_ALWAYS:OPEN_EXISTING);
        DWORD Access     = GENERIC_READ | (bWriteAccess?GENERIC_WRITE:0);

        hHandle = CreateFile(FFileName.c_str(), Access, ShareMode, NULL, CreateMode, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hHandle != INVALID_HANDLE_VALUE) {
            if (!bWriteAccess) {
                nnFileSize.LowPart = GetFileSize(hHandle, (unsigned long *)&nnFileSize.HighPart);
                FGeometry.Bytes = nnFileSize.QuadPart;
                CheckCompression();
            } else
                FGeometry.Bytes = 0; //-1;
            FGeometry.BytesPerSector = 0;
            FGeometry.BytesPerCluster = 0;
        } else
            return false;
        break;
    }  // case isFile:

    case isDrive: {
        PARTITION_INFORMATION PartitionInfo;
        DISK_GEOMETRY DiskGeometry;
        DWORD Dummy;



        // A example for a valid file name is: \\.\C

        DWORD Access     = GENERIC_READ | (bWriteAccess?GENERIC_WRITE:0);
        DWORD ShareMode  = (bWriteAccess?0:FILE_SHARE_READ|FILE_SHARE_WRITE);

        if (HaveNTCalls ) {
            wchar_t wFileName[255];
            int pos = 0;
            for (pos = 0; pos < FFileName.size(); pos++) {
                wFileName[pos] = FFileName[pos];
                wFileName[pos+1] = L'\0';
            }

            hHandle = NTOpen(wFileName, SYNCHRONIZE | Access, FILE_ATTRIBUTE_NORMAL, ShareMode, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
        } else {
            if (strncmp ("\\Device\\Floppy", FFileName.c_str(), 14) == 0) {
                printf ("Make open floppy fail\n");
                return false;
            }
            printf ("%s line %i: Try to open %s\n", __FILE__, __LINE__, FFileName.c_str());
            hHandle = CreateFile(FFileName.c_str(), GENERIC_READ, ShareMode, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_BACKUP_SEMANTICS, NULL);
        }

        if (hHandle != INVALID_HANDLE_VALUE) {
            bSuccess = DeviceIoControl(hHandle, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &PartitionInfo, sizeof(PartitionInfo), &Dummy, NULL);
            if (!bSuccess) {
                Close();
                return false;
            }
            bSuccess = DeviceIoControl(hHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY	, NULL, 0, &DiskGeometry, sizeof(DiskGeometry), &Dummy, NULL);
            if (!bSuccess) {
                Close();
                return false;
            }
            FGeometry.Bytes = (unsigned long long)PartitionInfo.PartitionLength.QuadPart;
            FGeometry.BytesPerSector = DiskGeometry.BytesPerSector;
#ifdef DEBUG_PARTSIZE
            printf("Bytes: %llu\n", FGeometry.Bytes);
            if ( FGeometry.Bytes == (__uint64)0)
                printf ("Hallo\n");
#endif

#if 0
            // Check to see if we're dealing with a floppy.  Does anyone have one any more?
            if (FFileName.Pos("Floppy") || FileName.Pos("A:") || FileName.Pos("B:"))
                FGeometry.Bytes = DiskGeometry.Cylinders.QuadPart * DiskGeometry.TracksPerCylinder * DiskGeometry.SectorsPerTrack * DiskGeometry.BytesPerSector;
#endif
        } else {
            printf ("invalid file handle\n");
            return false;
        }
#if 0
        CheckFileSystem();
#endif

        break;
    }  // case isDrive:

    case isNBD: {
        printf ("%s line %i: Here\n", __FILE__, __LINE__);
        return false;
#ifdef _WIN32
#if 0
        AnsiString Host;
        int nPort = 0;

        SplitConnectionString(FFileName, Host, nPort);

        if (NBDConnection)
            delete NBDConnection;
        NBDConnection = new TNBDClient(NULL);
        NBDConnection->Host = Host;
        NBDConnection->Port = nPort;
        NBDConnection->Timeout = SelfImageConfig->Values["NBDTimeout"];
        NBDConnection->TransactionSize = SelfImageConfig->Values["NBDTransactionSize"] * 1024;
        NBDConnection->Open();
        FGeometry.Bytes = NBDConnection->Size;
        CheckFileSystem();
#endif
#endif
    }  // case isNBD:

    default:
        // ERROR
        return false;
        break;
    }  // switch (Type)

    return (hHandle != INVALID_HANDLE_VALUE);
}  // bool __fastcall TImageStore::Open(void)
Beispiel #7
0
//------------------------------------------------------------------------------------
// запись данных в VFS
//------------------------------------------------------------------------------------
int	vw_WriteIntoVFSfromMemory(const char *Name, const BYTE * buffer, int size)
{

	// (!) пока работаем только с одной открытой VFS в системе, собственно больше и не нужно

	eVFS *WritebleVFS = StartVFS;

	if (WritebleVFS == 0)
	{
		fprintf(stderr, "Can't find VFS opened for write\n");
		return -1;
	}



	// Начальная подготовка структуры списка для новых данных
	eVFS_Entry *NewVFS_Entry = 0;
	NewVFS_Entry = new eVFS_Entry; if (NewVFS_Entry == 0) return -1;

	// первый в списке...
	if (EndVFSArray == 0)
	{
		NewVFS_Entry->Prev = 0;
		NewVFS_Entry->Next = 0;
		StarVFSArray = NewVFS_Entry;
		EndVFSArray = NewVFS_Entry;
	}
	else // продолжаем заполнение...
	{
		NewVFS_Entry->Prev = EndVFSArray;
		NewVFS_Entry->Next = 0;
		EndVFSArray->Next = NewVFS_Entry;
		EndVFSArray = NewVFS_Entry;
	}

	NewVFS_Entry->Parent = WritebleVFS;

	NewVFS_Entry->ArhKeyLen = 0;
	NewVFS_Entry->ArhKey = 0;
	NewVFS_Entry->NameLen = (DWORD)strlen(Name);

	NewVFS_Entry->Name = 0;
	NewVFS_Entry->Name = new char[NewVFS_Entry->NameLen+1];
	strcpy(NewVFS_Entry->Name, Name);

	NewVFS_Entry->Link = false;
	NewVFS_Entry->Offset = WritebleVFS->HeaderOffsetVFS; // т.к. это будет последний файл в структуре...
	NewVFS_Entry->Length = size;
	NewVFS_Entry->RealLength = size;








	// надо составлять свою ArhKeyVFS
	// 0 - 0
	int BestMode = 0;

#ifdef compression

	int BestSize = NewVFS_Entry->Length;
	int TmpSize = 0;


	// 1 - 1
	NewVFS_Entry->ArhKey = new char[1+1];
	NewVFS_Entry->ArhKey[0] = '1';
	NewVFS_Entry->ArhKey[1] = 0;
	TmpSize = CheckCompression(NewVFS_Entry->Length, buffer, NewVFS_Entry->ArhKey);
	if (TmpSize<BestSize)
	{
		BestMode = 1;
		BestSize = TmpSize;
	}

	// 2 - 2
	if (NewVFS_Entry->ArhKey != 0){delete [] NewVFS_Entry->ArhKey; NewVFS_Entry->ArhKey = 0;}
	NewVFS_Entry->ArhKey = new char[1+1];
	NewVFS_Entry->ArhKey[0] = '2';
	NewVFS_Entry->ArhKey[1] = 0;
	TmpSize = CheckCompression(NewVFS_Entry->Length, buffer, NewVFS_Entry->ArhKey);
	if (TmpSize<BestSize)
	{
		BestMode = 2;
		BestSize = TmpSize;
	}

	// 3 - 12
	if (NewVFS_Entry->ArhKey != 0){delete [] NewVFS_Entry->ArhKey; NewVFS_Entry->ArhKey = 0;}
	NewVFS_Entry->ArhKey = new char[2+1];
	NewVFS_Entry->ArhKey[0] = '1';
	NewVFS_Entry->ArhKey[0] = '2';
	NewVFS_Entry->ArhKey[1] = 0;
	TmpSize = CheckCompression(NewVFS_Entry->Length, buffer, NewVFS_Entry->ArhKey);
	if (TmpSize<BestSize)
	{
		BestMode = 3;
		BestSize = TmpSize;
	}

	// 4 - 21
	if (NewVFS_Entry->ArhKey != 0){delete [] NewVFS_Entry->ArhKey; NewVFS_Entry->ArhKey = 0;}
	NewVFS_Entry->ArhKey = new char[2+1];
	NewVFS_Entry->ArhKey[0] = '2';
	NewVFS_Entry->ArhKey[0] = '1';
	NewVFS_Entry->ArhKey[1] = 0;
	TmpSize = CheckCompression(NewVFS_Entry->Length, buffer, NewVFS_Entry->ArhKey);
	if (TmpSize<BestSize)
	{
		BestMode = 4;
		BestSize = TmpSize;
	}

#endif // compression

	if (NewVFS_Entry->ArhKey != 0){delete [] NewVFS_Entry->ArhKey; NewVFS_Entry->ArhKey = 0;}

	switch (BestMode)
	{
		default: // по умолчанию (0), или если неверный номер, не используем сжатие
			NewVFS_Entry->ArhKeyLen = 2;
			NewVFS_Entry->ArhKey = new char[NewVFS_Entry->ArhKeyLen];
			NewVFS_Entry->ArhKey[0] = '0';
			NewVFS_Entry->ArhKey[1] = 0;
			break;
		case 1:
			NewVFS_Entry->ArhKeyLen = 2;
			NewVFS_Entry->ArhKey = new char[NewVFS_Entry->ArhKeyLen];
			NewVFS_Entry->ArhKey[0] = '1';
			NewVFS_Entry->ArhKey[1] = 0;
			break;
		case 2:
			NewVFS_Entry->ArhKeyLen = 2;
			NewVFS_Entry->ArhKey = new char[NewVFS_Entry->ArhKeyLen];
			NewVFS_Entry->ArhKey[0] = '2';
			NewVFS_Entry->ArhKey[1] = 0;
			break;
		case 3:
			NewVFS_Entry->ArhKeyLen = 3;
			NewVFS_Entry->ArhKey = new char[NewVFS_Entry->ArhKeyLen];
			NewVFS_Entry->ArhKey[0] = '1';
			NewVFS_Entry->ArhKey[1] = '2';
			NewVFS_Entry->ArhKey[2] = 0;
			break;
		case 4:
			NewVFS_Entry->ArhKeyLen = 3;
			NewVFS_Entry->ArhKey = new char[NewVFS_Entry->ArhKeyLen];
			NewVFS_Entry->ArhKey[0] = '2';
			NewVFS_Entry->ArhKey[1] = '1';
			NewVFS_Entry->ArhKey[2] = 0;
			break;
	}








	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// если используется сжатие - запаковываем данные
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	// устанавливаем данные
	BYTE *dstVFS = 0;
	BYTE *srcVFS = 0;
	srcVFS = new BYTE[NewVFS_Entry->Length];
	memcpy(srcVFS, buffer, NewVFS_Entry->Length);
	int ssizeVFS = NewVFS_Entry->Length;

	if (!((NewVFS_Entry->ArhKey[0]=='0')&(strlen(NewVFS_Entry->ArhKey)==1)))
	{
		// цикл по кол-ву примененных методов сжатия в ArhKeyVFS
		for (unsigned int i=0; i<strlen(NewVFS_Entry->ArhKey);i++)
		{
			// находим, какой текущий метод сжатия
			char S = NewVFS_Entry->ArhKey[strlen(NewVFS_Entry->ArhKey)-i-1];

			// если RLE
			if (S == VFS_DATA_ARH_RLE)
			{
				vw_DATAtoRLE(&dstVFS, srcVFS, &NewVFS_Entry->Length, ssizeVFS);
				delete [] srcVFS; srcVFS = 0;
				srcVFS = dstVFS;
				ssizeVFS = NewVFS_Entry->Length;
				dstVFS = 0;

			}
			// если HAFF
			if (S == VFS_DATA_ARH_HAFF)
			{
				vw_DATAtoHAFF(&dstVFS, srcVFS, &NewVFS_Entry->Length, ssizeVFS);
				delete [] srcVFS; srcVFS = 0;
				srcVFS = dstVFS;
				ssizeVFS = NewVFS_Entry->Length;
				dstVFS = 0;
			}
		}
	}



	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// пишем данные в VFS
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	SDL_RWseek(WritebleVFS->File, WritebleVFS->HeaderOffsetVFS, SEEK_SET);
	SDL_RWwrite(WritebleVFS->File, srcVFS, NewVFS_Entry->Length, 1);
	delete [] srcVFS; srcVFS = 0;




	// переписывать все ентри, принадлежащие этому вфс файлу, в конец
	eVFS_Entry *Tmp = StarVFSArray;
	while (Tmp != 0)
	{
		eVFS_Entry *Tmp1 = Tmp->Next;

		// пишем только файлы (не линки)
		if ((!Tmp->Link) && (NewVFS_Entry->Parent == WritebleVFS))
		{
			SDL_RWwrite(WritebleVFS->File, &Tmp->ArhKeyLen, 1, 1);
			if (Tmp->ArhKeyLen > 0)
				SDL_RWwrite(WritebleVFS->File, Tmp->ArhKey, Tmp->ArhKeyLen, 1);
			SDL_RWwrite(WritebleVFS->File, &Tmp->NameLen, 2, 1);
			SDL_RWwrite(WritebleVFS->File, Tmp->Name, Tmp->NameLen, 1);
			SDL_RWwrite(WritebleVFS->File, &Tmp->Offset, 4, 1);
			SDL_RWwrite(WritebleVFS->File, &Tmp->Length, 4, 1);
			SDL_RWwrite(WritebleVFS->File, &Tmp->RealLength, 4, 1);
		}

		Tmp = Tmp1;
	}



	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// меняем данные
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	WritebleVFS->HeaderOffsetVFS += NewVFS_Entry->Length;
	WritebleVFS->HeaderLengthVFS += 1+NewVFS_Entry->ArhKeyLen+2+NewVFS_Entry->NameLen+4+4+4;


	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// переписываем смещение начала таблицы
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	SDL_RWseek(WritebleVFS->File, WritebleVFS->DataStartOffsetVFS, SEEK_SET);
	SDL_RWwrite(WritebleVFS->File, &WritebleVFS->HeaderOffsetVFS, 4, 1);
	SDL_RWwrite(WritebleVFS->File, &WritebleVFS->HeaderLengthVFS, 4, 1);


	printf("%s file added to VFS.\n", Name);

	return 0;
}
Beispiel #8
0
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum)
{
	unsigned modifiedTime = 0;
	if (CheckCachedData(fullName, &modifiedTime, doChecksum))
		return;

	isDirty = true;

	const std::string& fn    = FileSystem::GetFilename(fullName);
	const std::string& fpath = FileSystem::GetDirectory(fullName);
	const std::string& lcfn  = StringToLower(fn);

	std::unique_ptr<IArchive> ar(archiveLoader.OpenArchive(fullName));
	if (ar == nullptr || !ar->IsOpen()) {
		LOG_L(L_WARNING, "[AS::%s] unable to open archive \"%s\"", __func__, fullName.c_str());

		// record it as broken, so we don't need to look inside everytime
		BrokenArchive& ba = brokenArchives[lcfn];
		ba.path = fpath;
		ba.modified = modifiedTime;
		ba.updated = true;
		ba.problem = "Unable to open archive";

		// does not count as a scan
		// numScannedArchives += 1;
		return;
	}

	std::string error;
	std::string arMapFile; // file in archive with "smf" or "sm3" extension
	std::string miMapFile; // value for the 'mapfile' key parsed from mapinfo

	const bool hasModinfo = ar->FileExists("modinfo.lua");
	const bool hasMapinfo = ar->FileExists("mapinfo.lua");


	ArchiveInfo ai;
	ArchiveData& ad = ai.archiveData;

	// execute the respective .lua, otherwise assume this archive is a map
	if (hasMapinfo) {
		ScanArchiveLua(ar.get(), "mapinfo.lua", ai, error);

		if ((miMapFile = ad.GetMapFile()).empty()) {
			LOG_L(L_WARNING, "[AS::%s] set the 'mapfile' key in mapinfo.lua of archive \"%s\" for faster loading!", __func__, fullName.c_str());
			arMapFile = SearchMapFile(ar.get(), error);
		}
	} else if (hasModinfo) {
		ScanArchiveLua(ar.get(), "modinfo.lua", ai, error);
	} else {
		arMapFile = SearchMapFile(ar.get(), error);
	}

	if (!CheckCompression(ar.get(), fullName, error)) {
		// for some reason, the archive is marked as broken
		LOG_L(L_WARNING, "[AS::%s] failed to scan \"%s\" (%s)", __func__, fullName.c_str(), error.c_str());

		// record it as broken, so we don't need to look inside everytime
		BrokenArchive& ba = brokenArchives[lcfn];
		ba.path = fpath;
		ba.modified = modifiedTime;
		ba.updated = true;
		ba.problem = error;

		// does count as a scan
		numScannedArchives += 1;
		return;
	}

	if (hasMapinfo || !arMapFile.empty()) {
		// map archive
		if ((ad.GetName()).empty()) {
			// FIXME The name will never be empty, if version is set (see HACK in ArchiveData)
			ad.SetInfoItemValueString("name_pure", FileSystem::GetBasename(arMapFile));
			ad.SetInfoItemValueString("name", FileSystem::GetBasename(arMapFile));
		}

		if (miMapFile.empty())
			ad.SetInfoItemValueString("mapfile", arMapFile);

		AddDependency(ad.GetDependencies(), GetMapHelperContentName());
		ad.SetInfoItemValueInteger("modType", modtype::map);

		LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new map: %s", ad.GetNameVersioned().c_str());
	} else if (hasModinfo) {
		// game or base-type (cursors, bitmaps, ...) archive
		// babysitting like this is really no longer required
		if (ad.IsGame() || ad.IsMenu())
			AddDependency(ad.GetDependencies(), GetSpringBaseContentName());

		LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new game: %s", ad.GetNameVersioned().c_str());
	} else {
		// neither a map nor a mod: error
		error = "missing modinfo.lua/mapinfo.lua";
	}

	ai.path = fpath;
	ai.modified = modifiedTime;
	ai.origName = fn;
	ai.updated = true;
	ai.checksum = (doChecksum) ? GetCRC(fullName) : 0;
	archiveInfos[lcfn] = ai;

	numScannedArchives += 1;
}
Beispiel #9
0
int main(int argc, char **argv) {
	int retval = 0;
	char *dparams[2];
	int paramc = 0, params = -1;

	char temp[0x1000];
	int done = 0;
	char *source = NULL;
	int n = 0;

	// Acción a realizar
	int action = ACTION_NONE;

	if (argc <= 1) {
		action = ACTION_HELP;
		setparams(0);
	}

	for (n = 1; n <= argc; n++) {
		char *arg;
		arg = (n < argc) ? argv[n] : "";

		//printf("%s\n", arg);

		// Muestra la ayuda y sale
		if (strcmp(arg, "-?") == 0 || strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
			//show_help();
			action = ACTION_HELP;
			setparams(0);
		}

		// Modificadores
		{
			// Modo raw (sin cabeceras de compresión)
			if (strcmp(arg, "-r") == 0 || strcmp(arg, "-raw") == 0) { raw = 1; continue; }

			// Modo silencioso
			if (strcmp(arg, "-s") == 0) { silent = 1; fclose(stdout); continue; }
		}

		// Acciones
		{
			if (arg[0] == '-') {
				int cnt = 1;

				switch (arg[1]) {
					// Codificad
					case 'c': action = ACTION_ENCODE ; setparams(2); break;
					// Decodificia
					case 'd': action = ACTION_DECODE ; setparams(2); break;
					// Comprueba
					case 't': action = ACTION_TEST   ; setparams(1); break;
					// Crea un perfil de compresión
					case 'p': action = ACTION_PROFILE; setparams(1); break;
					// Dumpea el text_buffer inicial
					case 'b': action = ACTION_BDUMP  ; setparams(1); break;
					default:  cnt = 0; break;
				}

				if (cnt) {
					done = 0;
					modifier = (strlen(arg) >= 3) ? atoi(arg + 2) : 3;
					continue;
				}
			}
		}

		if ((n < argc) && (paramc < params)) {
			dparams[paramc++] = arg;
		}

		if (paramc >= params) {
			show_header_once();

			done = 1;
			switch (action) {
				case ACTION_ENCODE:
					if (strcmp(dparams[0], dparams[1]) != 0) {
						retval |= EncodeFile(dparams[0], dparams[1], raw, modifier);
					} else {
						fprintf(stderr, "Can't use same file for input and output\n");
						retval |= -1;
					}
				break;
				case ACTION_DECODE:
					if (strcmp(dparams[0], dparams[1]) != 0) {
						retval |= DecodeFile(dparams[0], dparams[1], raw, modifier);
					} else {
						fprintf(stderr, "Can't use same file for input and output\n");
						retval |= -1;
					}
				break;
				case ACTION_PROFILE:
					if (strlen(arg) < 0x900) {
						sprintf(temp, "%s.profile", arg);
						ProfileStart(temp);
							retval |= DecodeFile(dparams[0], NULL, raw, modifier);
						ProfileEnd();
					}
				break;
				case ACTION_BDUMP:
					DumpTextBuffer(dparams[0]);
				break;
				case ACTION_TEST:
					retval |= CheckCompression(dparams[0], modifier);
				break;
				case ACTION_HELP:
					show_help();
				break;
				default:
					if (n == argc) {
						if (paramc == params || params == 0) exit(retval);
						if (params == -1) show_help();
						fprintf(stderr, "Expected %d params, but %d given\n", params, paramc);
						exit(-1);
					}
					fprintf(stderr, "Unknown parameter '%s'\n", arg);
					exit(-1);
				break;
			}

			paramc = params = 0;
			action = ACTION_NONE;
		}
	}

	show_header_once();

	fprintf(stderr, "Expected %d params, but %d given\n", params, paramc);
	exit(-1);

	return 0;
}