/* * Finds the central directory end record in the end of the file. * Returns true if it successfully located. This gets awfully slow if * the comment is long. */ boolean Zip_LocateCentralDirectory(DFILE * file) { /* int length = F_Length(file); */ int pos = CENTRAL_END_SIZE; // Offset from the end. uint signature; // Start from the earliest location where the signature might be. while(pos < MAXIMUM_COMMENT_SIZE) { F_Seek(file, -pos, SEEK_END); // Is this is signature? F_Read(&signature, 4, file); if(signature == SIG_END_OF_CENTRAL_DIR) { // This is it! return true; } // Move backwards. pos++; } // Scan was not successful. return false; }
//=========================================================================== // W_ReadLumpSection //=========================================================================== void W_ReadLumpSection(int lump, void *dest, int startoffset, int length) { int c; lumpinfo_t *l; if(lump >= numlumps) { Con_Error("W_ReadLumpSection: %i >= numlumps", lump); } l = lumpinfo + lump; F_Seek(l->handle, l->position + startoffset, SEEK_SET); c = F_Read(dest, length, l->handle); if(c < length) { Con_Error("W_ReadLumpSection: only read %i of %i on lump %i", c, length, lump); } }
void W_ReadLump(int lump, void *dest) { int c; lumpinfo_t *l; if(lump >= numlumps) { Con_Error("W_ReadLump: %i >= numlumps", lump); } l = lumpinfo + lump; F_Seek(l->handle, l->position, SEEK_SET); c = F_Read(dest, l->size, l->handle); if(c < l->size) { Con_Error("W_ReadLump: only read %i of %i on lump %i", c, l->size, lump); } }
/* * Reads a zipentry into the buffer. The buffer must be large enough. * Zip_GetSize() returns the size. Returns the number of bytes read. */ uint Zip_Read(zipindex_t index, void *buffer) { package_t *pack; zipentry_t *entry; index--; if(index < 0 || index >= zipNumFiles) return 0; // Doesn't exist. entry = zipFiles + index; pack = entry->package; VERBOSE2(Con_Printf ("Zip_Read: %s: '%s' (%i bytes)\n", M_Pretty(pack->name), M_Pretty(entry->name), entry->size)); //Con_Printf("Zip_Read: offset=%i\n", entry->offset); F_Seek(pack->file, entry->offset, SEEK_SET); F_Read(buffer, entry->size, pack->file); // TODO: Use zlib to inflate deflated entries. return entry->size; }
boolean W_AddFile(const char *filename, boolean allowDuplicate) { char alterFileName[256]; wadinfo_t header; DFILE *handle; unsigned int length; filelump_t *fileinfo, singleinfo; filelump_t *freeFileInfo; filerecord_t *rec; const char *extension; // Filename given? if(!filename || !filename[0]) return true; if((handle = F_Open(filename, "rb")) == NULL) { // Didn't find file. Try reading from the data path. R_PrependDataPath(filename, alterFileName); if((handle = F_Open(alterFileName, "rb")) == NULL) { Con_Message("W_AddFile: ERROR: %s not found!\n", filename); return false; } // We'll use this instead. filename = alterFileName; } // Do not read files twice. if(!allowDuplicate && !M_CheckFileID(filename)) { F_Close(handle); // The file is not used. return false; } Con_Message("W_AddFile: %s\n", M_Pretty(filename)); // Determine the file name extension. extension = strrchr(filename, '.'); if(!extension) extension = ""; else extension++; // Move to point after the dot. // Is it a zip/pk3 package? if(!stricmp(extension, "zip") || !stricmp(extension, "pk3")) { return Zip_Open(filename, handle); } // Get a new file record. rec = W_RecordNew(); strcpy(rec->filename, filename); convertSlashes(rec->filename); rec->handle = handle; // If we're not loading for startup, flag the record to be a Runtime one. if(!loadingForStartup) rec->flags = FRF_RUNTIME; if(stricmp(extension, "wad") && stricmp(extension, "gwa")) { // Single lump file. fileinfo = &singleinfo; freeFileInfo = NULL; singleinfo.filepos = 0; singleinfo.size = F_Length(handle); M_ExtractFileBase(filename, singleinfo.name); rec->numlumps = 1; } else { // WAD file. F_Read(&header, sizeof(header), handle); if(!strncmp(header.identification, "JWAD", 4)) { // This is treated like an IWAD, but we won't set the // iwadLoaded flag. rec->iwad = true; } else if(strncmp(header.identification, "IWAD", 4)) { if(strncmp(header.identification, "PWAD", 4)) { // Bad file id Con_Error("Wad file %s doesn't have IWAD or PWAD id\n", filename); } } else { // Found an IWAD. iwadLoaded = true; if(!stricmp(extension, "wad")) rec->iwad = true; } header.numlumps = LONG(header.numlumps); header.infotableofs = LONG(header.infotableofs); length = header.numlumps * sizeof(filelump_t); if(!(fileinfo = malloc(length))) { Con_Error("W_AddFile: fileinfo malloc failed\n"); } freeFileInfo = fileinfo; F_Seek(handle, header.infotableofs, SEEK_SET); F_Read(fileinfo, length, handle); rec->numlumps = header.numlumps; } // Insert the lumps to lumpinfo, into their rightful places. W_InsertLumps(fileinfo, rec); if(freeFileInfo) free(freeFileInfo); PrimaryLumpInfo = lumpinfo; PrimaryLumpCache = lumpcache; PrimaryNumLumps = numlumps; // Print the 'CRC' number of the IWAD, so it can be identified. if(rec->iwad) Con_Message(" IWAD identification: %08x\n", W_CRCNumberForRecord(rec - records)); // glBSP: Also load a possible GWA. if(!stricmp(extension, "wad")) { char buff[256]; strcpy(buff, filename); strcpy(buff + strlen(buff) - 3, "gwa"); // If GL data exists, load it. if(F_Access(buff)) { W_AddFile(buff, allowDuplicate); } } return true; }
uint8_t Update_Font(void) { uint32_t fcluster=0; uint32_t i; //uint8_t temp[512]; //零时空间 在这里定义,会内存溢出 uint32_t tempsys[2]; //临时记录文件起始位置和文件大小 float prog; uint8_t t; FileInfoStruct FileTemp;//零时文件夹 //得到根目录的簇号 if(FAT32_Enable)fcluster=FirstDirClust; else fcluster=0; FileTemp=F_Search(fcluster,(unsigned char *)folder[0],T_FILE);//查找system文件夹 if(FileTemp.F_StartCluster==0)return 1; //系统文件夹丢失 { //先查找字体 FileTemp=F_Search(FileTemp.F_StartCluster,(unsigned char *)folder[1],T_FILE);//在system文件夹下查找FONT文件夹 if(FileTemp.F_StartCluster==0)return 2;//字体文件夹丢失 fcluster=FileTemp.F_StartCluster; //字体文件夹簇号 FileTemp=F_Search(fcluster,(unsigned char *)sysfile[2],T_SYS);//在system文件夹下查找SYS文件 if(FileTemp.F_StartCluster==0)return 3;//FONT12字体文件丢失 LCD_ShowString1(20,90,"Write UNI2GBK to FLASH...",RED,BLACK); LCD_ShowString1(108,110,"%",RED,BLACK); F_Open(&FileTemp);//打开该文件 i=0; while(F_Read(&FileTemp,temp))//成功读出512个字节 { if(i<FileTemp.F_Size)//不超过文件大小 { M45PE_Write(temp,i+100000,512);//从100K字节处开始写入512个数据 i+=512;//增加512个字节 } prog=(float)i/FileTemp.F_Size; prog*=100; if(t!=prog) { t=prog; if(t>100)t=100; LCD_ShowNum1(84,110,t,3,16);//显示数值 } } UNI2GBKADDR=100000;//UNI2GBKADDR从100K处开始写入. tempsys[0]=UNI2GBKADDR; tempsys[1]=FileTemp.F_Size; //UNI2GBKADDR 大小 M45PE_Write((uint8_t*)tempsys,0,8);//记录在地址0~7处 Delay(1000); //printf("UNI2GBK写入FLASH完毕!\n"); //printf("写入数据长度:%d\n",FileTemp.F_Size); //printf("UNI2GBKSADDR:%d\n\n",UNI2GBKADDR); FONT16ADDR=FileTemp.F_Size+UNI2GBKADDR;//F16的首地址 FileTemp=F_Search(fcluster,(unsigned char *)sysfile[0],T_FON);//在system文件夹下查找FONT16字体文件 if(FileTemp.F_StartCluster==0)return 4;//FONT16字体文件丢失 LCD_ShowString1(20,90,"Write FONT16 to FLASH... ",RED,BLACK); //printf("开始FONT16写入FLASH...\n"); F_Open(&FileTemp);//打开该文件 i=0; while(F_Read(&FileTemp,temp))//成功读出512个字节 { if(i<FileTemp.F_Size)//不超过文件大小 { M45PE_Write(temp,i+FONT16ADDR,512);//从0开始写入512个数据 i+=512;//增加512个字节 } prog=(float)i/FileTemp.F_Size; prog*=100; if(t!=prog) { t=prog; if(t>100)t=100; LCD_ShowNum1(84,110,t,3,16);//显示数值 } } tempsys[0]=FONT16ADDR; tempsys[1]=FileTemp.F_Size; //FONT16ADDR 大小 M45PE_Write((uint8_t*)tempsys,8,8);//记录在地址8~15处 Delay(1000); //printf("FONT16写入FLASH完毕!\n"); //printf("写入数据长度:%d\n",FileTemp.F_Size); FONT12ADDR=FileTemp.F_Size+FONT16ADDR;//F16的首地址 //printf("FONT16SADDR:%d\n\n",FONT16ADDR); //LCD_ShowString(20,60,"Write FONT12 to FLASH... "); //FONT12暂时不加入 /* FileTemp=F_Search(fcluster,(unsigned char *)sysfile[1],T_FON);//在system文件夹下查找FONT12字体文件 if(FileTemp.F_StartCluster==0)return 5;//FONT12字体文件丢失 printf("开始FONT12写入FLASH...\n"); F_Open(&FileTemp);//打开该文件 i=0; while(F_Read(&FileTemp,temp))//成功读出512个字节 { if(i<FileTemp.F_Size)//不超过文件大小 { M45PE_Write(temp,i+FONT12ADDR,512);//从0开始写入512个数据 i+=512;//增加512个字节 } prog=(float)i/FileTemp.F_Size; prog*=100; if(t!=prog) { t=prog; if(t>100)t=100; LCD_ShowNum(84,80,t,3,16);//显示数值 } } tempsys[0]=FONT12ADDR; tempsys[1]=FileTemp.F_Size; //FONT16ADDR 大小 M45PE_Write((uint8_t*)tempsys,16,8);//记录在地址16~23处 printf("FONT12写入FLASH完毕!\n"); printf("写入数据长度:%d\n",FileTemp.F_Size); printf("FONT12SADDR:%d\n\n",FONT12ADDR); */ } t=0xBB; M45PE_Write(&t,24,1);//写入字库存在标志 0XAA LCD_ShowString1(20,90," Font Update Successed ",RED,BLACK); Delay(1000); Delay(1000); return 0;//成功 }
/* * Opens the file zip, reads the directory and stores the info for later * access. If prevOpened is not NULL, all data will be read from there. */ boolean Zip_Open(const char *fileName, DFILE * prevOpened) { DFILE *file; package_t *pack; centralend_t summary; void *directory; char *pos; char buf[512]; zipentry_t *entry; int index; if(prevOpened == NULL) { // Try to open the file. if((file = F_Open(fileName, "rb")) == NULL) { Con_Message("Zip_Open: %s not found.\n", fileName); return false; } } else { // Use the previously opened file. file = prevOpened; } VERBOSE(Con_Message("Zip_Open: %s\n", M_Pretty(fileName))); // Scan the end of the file for the central directory end record. if(!Zip_LocateCentralDirectory(file)) { Con_Error("Zip_Open: %s: Central directory not found.\n", M_Pretty(fileName)); } // Read the central directory end record. F_Read(&summary, sizeof(summary), file); // Does the summary say something we don't like? if(summary.diskEntryCount != summary.totalEntryCount) { Con_Error("Zip_Open: %s: Multipart Zip files are not supported.\n", M_Pretty(fileName)); } // Read the entire central directory into memory. directory = malloc(summary.size); F_Seek(file, summary.offset, SEEK_SET); F_Read(directory, summary.size, file); pack = Zip_NewPackage(); strcpy(pack->name, fileName); pack->file = file; // Read all the entries. pos = directory; for(index = 0; index < summary.totalEntryCount; index++, pos += sizeof(centralfileheader_t)) { localfileheader_t localHeader; centralfileheader_t *header = (void *) pos; char *nameStart = pos + sizeof(centralfileheader_t); // Advance the cursor past the variable sized fields. pos += header->fileNameSize + header->extraFieldSize + header->commentSize; Zip_CopyStr(buf, nameStart, header->fileNameSize, sizeof(buf)); // Directories are skipped. if(buf[header->fileNameSize - 1] == '/' && !header->size) continue; // Do we support the format of this file? if(header->compression != ZFC_NO_COMPRESSION || header->compressedSize != header->size) { Con_Error("Zip_Open: %s: '%s' is compressed.\n Compression is " "not supported.\n", M_Pretty(fileName), buf); } if(header->flags & ZFH_ENCRYPTED) { Con_Error("Zip_Open: %s: '%s' is encrypted.\n Encryption is " "not supported.\n", M_Pretty(fileName), buf); } // Convert all slashes to backslashes, for compatibility with // the sys_filein routines. Dir_FixSlashes(buf); // Make it absolute. M_PrependBasePath(buf, buf); // We can add this file to the zipentry list. entry = Zip_NewFile(buf); entry->package = pack; entry->size = header->size; // Read the local file header, which contains the correct // extra field size (Info-ZIP!). F_Seek(file, header->relOffset, SEEK_SET); F_Read(&localHeader, sizeof(localHeader), file); entry->offset = header->relOffset + sizeof(localfileheader_t) + header->fileNameSize + localHeader.extraFieldSize; } // The central directory is no longer needed. free(directory); Zip_SortFiles(); Zip_RemoveDuplicateFiles(); // File successfully opened! return true; }