📄 mpq.cpp
字号:
case LIBMPQ_FILE_TYPE_CHAR:
for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) {
sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i);
if (strncmp(tempfile, (char *)file, strlen((char *)file)) == 0) {
/* if file found break */
found = 1;
break;
}
}
/* if a file was found return 0 */
if (found == 1) {
return LIBMPQ_TOOLS_SUCCESS;
} else {
return LIBMPQ_EFILE_NOT_FOUND;
}
default:
return LIBMPQ_TOOLS_SUCCESS;
}
}
/*
* This function extracts a file from a MPQ archive
* by the given number.
*/
int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename) {
int blockindex = number; //-1;
int fd = 0;
int i = 0;
char buffer[0x1000];
//char tempfile[PATH_MAX];
unsigned int transferred = 1;
mpq_file *mpq_f = NULL;
mpq_block *mpq_b = NULL;
mpq_hash *mpq_h = NULL;
/* if (number < 1 || number > mpq_a->header->blocktablesize) {
return LIBMPQ_EINV_RANGE;
}*/
/*
sprintf(tempfile, libmpq_file_name(mpq_a, number));
*/
/* check if mpq_f->filename could be written here. */
fd = _open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
if (fd == LIBMPQ_EFILE) {
return LIBMPQ_EFILE;
}
/* search for correct hashtable */
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
blockindex = (mpq_a->hashtable[i]).blockindex;
mpq_h = &(mpq_a->hashtable[i]);
break;
}
}*/
/* check if file was found */
if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
return LIBMPQ_EFILE_NOT_FOUND;
}
/* check if sizes are correct */
mpq_b = mpq_a->blocktable + blockindex;
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
return LIBMPQ_EFILE_CORRUPT;
}
/* check if file exists */
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
return LIBMPQ_EFILE_NOT_FOUND;
}
/* allocate memory for file structure */
mpq_f = (mpq_file *)malloc(sizeof(mpq_file));
if (!mpq_f) {
return LIBMPQ_EALLOCMEM;
}
/* initialize file structure */
memset(mpq_f, 0, sizeof(mpq_file));
mpq_f->fd = fd;
mpq_f->mpq_b = mpq_b;
mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
mpq_f->mpq_h = mpq_h;
mpq_f->accessed = FALSE;
mpq_f->blockposloaded = FALSE;
sprintf((char *)mpq_f->filename, filename);
/* allocate buffers for decompression. */
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
/*
* Allocate buffer for block positions. At the begin of file are stored
* unsigned ints holding positions of each block relative from begin of
* file in the archive.
*/
if ((mpq_f->blockpos = (unsigned int *)malloc(sizeof(int) * mpq_f->nblocks + 1)) == NULL) {
return LIBMPQ_EALLOCMEM;
}
}
while (transferred > 0) {
transferred = libmpq_file_read_file(mpq_a, mpq_f, mpq_f->filepos, buffer, sizeof(buffer));
if (transferred == 0) {
break;
} else {
mpq_f->accessed = TRUE;
mpq_f->filepos += transferred;
}
transferred = _write(mpq_f->fd, buffer, transferred);
if (transferred == 0) {
break;
}
}
_close(fd);
/* freeing the file structure */
free(mpq_f);
return LIBMPQ_TOOLS_SUCCESS;
}
/*
* This function tries to get the filenames for the hashes. It uses
* an internal listfile database and gets the correct listfile from
* some specific archive informations.
*/
int libmpq_listfile_open(mpq_archive *mpq_a, char file[PATH_MAX]) {
FILE *fp;
//char **filelist;
int i = 0;
//int fl_count;
//int fl_size;
int fl_count_fb;
int fl_size_fb;
int result = LIBMPQ_TOOLS_SUCCESS;
struct stat statbuf;
/* get file status */
if (stat(file, &statbuf) < 0) {
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
}
/* check if file is a filename or directory */
/*if (S_ISDIR(statbuf.st_mode)) {
// allocate memory for the file list
filelist = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
fl_count = 0;
fl_size = LIBMPQ_CONF_FL_INCREMENT;
// check if it is a valid listfile
if (libmpq_detect_listfile_rec(file, &filelist, &fl_count, &fl_size)) {
filelist == NULL;
}
filelist[fl_count] = NULL;
// return if no listfile was found
if (filelist == NULL) {
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
}
for (i = 0; filelist[i]; i++) {
if ((fp = fopen(filelist[i], "r")) != NULL ) {
result = libmpq_read_listfile(mpq_a, fp);
fclose(fp);
}
}
// freeing the listfile struct
libmpq_free_listfile(filelist);
}*/
/* if file is a regular file use it */
//if (S_ISREG(statbuf.st_mode)) {
/* if specific listfile was forced. */
if ((fp = fopen(file, "r")) != NULL ) {
result = libmpq_read_listfile(mpq_a, fp);
fclose(fp);
} else {
result = LIBMPQ_CONF_EFILE_OPEN;
}
//}
/* if error occured we need to create a fallback filelist. */
if (mpq_a->mpq_l->mpq_files == NULL) {
/* allocate memory for the file list */
mpq_a->mpq_l->mpq_files = (unsigned char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
fl_count_fb = 0;
fl_size_fb = LIBMPQ_CONF_FL_INCREMENT;
for (i = 0; i < libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES); i++) {
/* set the next filelist entry to a copy of the file */
mpq_a->mpq_l->mpq_files[fl_count_fb++] = (unsigned char *)_strdup("file%06lu.xxx");
/* increase the array size */
if (fl_count_fb == fl_size_fb) {
mpq_a->mpq_l->mpq_files = (unsigned char **)realloc(mpq_a->mpq_l->mpq_files, (fl_size_fb + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *));
fl_size_fb += LIBMPQ_CONF_FL_INCREMENT;
}
}
mpq_a->mpq_l->mpq_files[fl_count_fb] = NULL;
/* if no error occurs and no listfile was assigned, we think there was no matching listfile. */
if (result == 0) {
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
}
}
return result;
}
/*
* This function frees the allocated memory for the listfile.
*/
int libmpq_listfile_close(mpq_archive *mpq_a) {
int i = 0;
/* safety check if we really have a filelist. */
if (mpq_a->mpq_l->mpq_files != NULL) {
/* freeing the filelist */
while (mpq_a->mpq_l->mpq_files[i]) {
free(mpq_a->mpq_l->mpq_files[i++]);
}
free(mpq_a->mpq_l->mpq_files);
}
return 0;
}
int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest) {
int blockindex = number; //-1;
int i = 0;
mpq_file *mpq_f = NULL;
mpq_block *mpq_b = NULL;
int success = 0;
/*if (number < 1 || number > mpq_a->header->blocktablesize) {
return LIBMPQ_EINV_RANGE;
}*/
/* search for correct hashtable */
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
blockindex = (mpq_a->hashtable[i]).blockindex;
mpq_h = &(mpq_a->hashtable[i]);
break;
}
}*/
/* check if file was found */
if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
return LIBMPQ_EFILE_NOT_FOUND;
}
/* check if sizes are correct */
mpq_b = mpq_a->blocktable + blockindex;
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
return LIBMPQ_EFILE_CORRUPT;
}
/* check if file exists */
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
return LIBMPQ_EFILE_NOT_FOUND;
}
/* allocate memory for file structure */
mpq_f = (mpq_file*)malloc(sizeof(mpq_file));
if (!mpq_f) {
return LIBMPQ_EALLOCMEM;
}
/* initialize file structure */
memset(mpq_f, 0, sizeof(mpq_file));
mpq_f->mpq_b = mpq_b;
mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
mpq_f->mpq_h = &mpq_h;
mpq_f->accessed = FALSE;
mpq_f->blockposloaded = FALSE;
/* allocate buffers for decompression. */
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
/*
* Allocate buffer for block positions. At the begin of file are stored
* unsigned ints holding positions of each block relative from begin of
* file in the archive.
*/
if ((mpq_f->blockpos = (unsigned int*)malloc(sizeof(int) * (mpq_f->nblocks + 1))) == NULL) {
return LIBMPQ_EALLOCMEM;
}
}
if(libmpq_file_read_file(mpq_a, mpq_f, 0, (char*)dest, mpq_b->fsize) == mpq_b->fsize)
success = 1;
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
// Free buffer for block positions
free(mpq_f->blockpos);
}
/* freeing the file structure */
free(mpq_f);
return success?LIBMPQ_TOOLS_SUCCESS:LIBMPQ_EFILE_CORRUPT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -