Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- This may be a bit overcooked. I prompted ChatGPT to "continue" many, many times. Some functions are duplicated. But I had it keep going just in case it missed anything. This code would need to be heavily cleaned up if someone actually wanted to run it. It references an "mcard.h", which also exists in the fake linux directory. This is the "mcard.c" file.
- /*
- * PSX Memory Card Save File Extractor
- * Copyright (C) 2011-2020 Onpon4 <[email protected]>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "mcard.h"
- /* These are the global variables used in this program. */
- char mcname[13]; // The name of the memory card file.
- unsigned char mcdata[MC_SIZE]; // The data of the memory card file.
- unsigned int mcsize; // The size of the memory card file.
- unsigned char *cur; // A pointer to the current position in mcdata.
- int binflag; // Whether to output in binary format.
- int infoflag; // Whether to show file information.
- int listflag; // Whether to list all files.
- int extractflag; // Whether to extract all files.
- int onlyfileflag; // Whether to extract only the specified file.
- char outdir[1024]; // The directory to output to.
- char onlyfile[13]; // The file to extract only.
- enum Format inputformat; // The format of the input file.
- /* This is the main function. */
- int main(int argc, char *argv[])
- {
- /* Initialize variables. */
- binflag = 0;
- infoflag = 0;
- listflag = 0;
- extractflag = 0;
- onlyfileflag = 0;
- strcpy(outdir, ".");
- inputformat = UNKNOWN;
- /* Parse arguments. */
- if(argc == 1)
- {
- fprintf(stderr, "Error: No memory card file specified.\n");
- return 1;
- }
- for(int i = 1; i < argc; i++)
- {
- if(argv[i][0] == '-')
- {
- if(strlen(argv[i]) != 2)
- {
- fprintf(stderr, "Error: Invalid option: %s\n", argv[i]);
- return 1;
- }
- switch(argv[i][1])
- {
- case 'b':
- binflag = 1;
- break;
- case 'i':
- infoflag = 1;
- break;
- case 'l':
- listflag = 1;
- break;
- case 'x':
- extractflag = 1;
- break;
- case 'o':
- if(i == argc - 1)
- {
- fprintf(stderr, "Error: -o option requires an argument.\n");
- return 1;
- }
- i++;
- strcpy(outdir, argv[i]);
- break;
- case 'f':
- if(i == argc - 1)
- {
- fprintf(stderr, "Error: -f option requires an argument.\n");
- return 1;
- }
- i++;
- onlyfileflag = 1;
- strcpy(onlyfile, argv[i]);
- break;
- case 'F':
- if(i == argc - 1)
- {
- fprintf(stderr, "Error: -F option requires an argument.\n");
- return 1;
- }
- i++;
- if(strcmp(argv[i], "mcr") == 0)
- {
- inputformat = MCR;
- }
- else if(strcmp(argv[i], "gme") == 0)
- {
- inputformat = GME;
- }
- else
- {
- fprintf(stderr, "Error: Invalid format: %s\n", argv[i]);
- return 1;
- }
- break;
- default:
- fprintf(stderr, "Error: Invalid option: %s\n", argv[i]);
- return 1;
- }
- }
- else
- {
- if(strlen(argv[i]) > 12)
- {
- fprintf(stderr, "Error: Memory card file name too long: %s\n", argv[i]);
- return 1;
- }
- strcpy(mcname, argv[i]);
- }
- }
- /* Open the memory card file. */
- FILE *file = fopen(mcname, "rb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open memory card file: %s\n", mcname);
- return 1;
- }
- /* Get the size of the memory card file. */
- fseek(file, 0, SEEK_END);
- mcsize = ftell(file);
- fseek(file, 0, SEEK_SET);
- /* Read the memory card file. */
- if(fread(mcdata, 1, mcsize, file) != mcsize)
- {
- fprintf(stderr, "Error: Could not read memory card file: %s\n", mcname);
- fclose(file);
- return 1;
- }
- /* Close the memory card file. */
- fclose(file);
- /* Parse the memory card file. */
- cur = mcdata;
- /* Check the format of the memory card file. */
- if(mcsize == MC_SIZE && inputformat == UNKNOWN)
- {
- inputformat = MCR;
- }
- else if(mcsize == GME_SIZE && inputformat == UNKNOWN)
- {
- inputformat = GME;
- }
- else if(inputformat == UNKNOWN)
- {
- fprintf(stderr, "Error: Unknown format of memory
- card file: %s\n", mcname);
- return 1;
- }
- /* Check if the specified file is available. */
- if(onlyfileflag && !file_available(onlyfile))
- {
- fprintf(stderr, "Error: Specified file not found: %s\n", onlyfile);
- return 1;
- }
- /* Show information about the memory card file. */
- if(infoflag)
- {
- printf("Memory card file: %s\n", mcname);
- printf("Format: ");
- if(inputformat == MCR)
- {
- printf("MCR\n");
- }
- else if(inputformat == GME)
- {
- printf("GME\n");
- }
- printf("Size: %d\n", mcsize);
- printf("Free space: %d\n", get_free_space());
- printf("Number of files: %d\n", get_num_files());
- }
- /* List all files on the memory card. */
- if(listflag)
- {
- printf("Files on memory card %s:\n", mcname);
- if(inputformat == MCR)
- {
- list_mcr_files();
- }
- else if(inputformat == GME)
- {
- list_gme_files();
- }
- }
- /* Extract all files from the memory card. */
- if(extractflag)
- {
- if(inputformat == MCR)
- {
- extract_mcr_files();
- }
- else if(inputformat == GME)
- {
- extract_gme_files();
- }
- }
- /* Extract only the specified file from the memory card. */
- if(onlyfileflag)
- {
- if(inputformat == MCR)
- {
- extract_mcr_file(onlyfile);
- }
- else if(inputformat == GME)
- {
- extract_gme_file(onlyfile);
- }
- }
- return 0;
- }
- /* This function checks if a file is available on the memory card. */
- int file_available(char *file)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is the file we're looking for. */
- if(strncmp(file, (char *)(cur + 0x10), 12) == 0)
- {
- return 1;
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is the file we're looking for. */
- if(strncmp(file, (char *)(cur + 0x10), 12) == 0)
- {
- return 1;
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* The file is not available. */
- return 0;
- }
- /* This function gets the number of files on the memory card. */
- int get_num_files(void)
- {
- int num = 0;
- /* Get the number of files in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- num++;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* Get the number of files in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- num++;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- return num;
- }
- /* This function gets the amount of free space on the memory card. */
- int get_free_space(void)
- {
- int free_space = 0;
- /* Get the amount of free space in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the allocation table of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each allocation table entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is not allocated. */
- if(cur[0] == 0 && cur[1] == 0)
- {
- free_space += 0x2000;
- }
- /* Go to the next allocation table entry. */
- cur += 0x2;
- }
- }
- /* Get the amount of free space in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the allocation table of the memory card. */
- cur = mcdata + 0x1c00;
- /* Check each allocation table entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is not allocated. */
- if(cur[0] == 0 && cur[1] == 0)
- {
- free_space += 0x1000;
- }
- /* Go to the next allocation table entry. */
- cur += 0x2;
- }
- }
- return free_space;
- }
- /* This function lists all files on the memory card in MCR format. */
- void list_mcr_files(void)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Print the file name. */
- printf(" ");
- for(int j = 0; j < 12; j++)
- {
- putchar(cur[0x10 + j]);
- }
- putchar('\n');
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* This function lists all files on the memory card in GME format. */
- void list_gme_files(void)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Print the file name. */
- printf(" ");
- for(int j = 0; j < 12; j++)
- {
- putchar(cur[0x10 + j]);
- }
- putchar('\n');
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* This function extracts all files from the memory card in MCR format. */
- void extract_mcr_files(void)
- {
- /* Go to
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Get the file name. */
- char filename[13];
- strncpy(filename, (char *)(cur + 0x10), 12);
- filename[12] = '\0';
- /* Get the file size. */
- int filesize = cur[0x1c] | (cur[0x1d] << 8);
- /* Go to the first block of the file. */
- int block = cur[2] | (cur[3] << 8);
- /* Create the file. */
- FILE *file = fopen(filename, "wb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not create file: %s\n", filename);
- continue;
- }
- /* Write the file data. */
- while(block != 0xffff)
- {
- /* Go to the block data. */
- cur = mcdata + block * 0x2000;
- /* Write the block data to the file. */
- if(fwrite(cur, 1, 0x2000, file) != 0x2000)
- {
- fprintf(stderr, "Error: Could not write to file: %s\n", filename);
- fclose(file);
- remove(filename);
- return;
- }
- /* Get the next block. */
- block = cur[0x1fe] | (cur[0x1ff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Truncate the file if necessary. */
- if(filesize < get_file_size(filename))
- {
- file = fopen(filename, "rb+");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", filename);
- return;
- }
- ftruncate(fileno(file), filesize);
- fclose(file);
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* This function extracts all files from the memory card in GME format. */
- void extract_gme_files(void)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Get the file name. */
- char filename[13];
- strncpy(filename, (char *)(cur + 0x10), 12);
- filename[12] = '\0';
- /* Get the file size. */
- int filesize = cur[0
- /* Get the next block. */
- block = cur[0x3fe] | (cur[0x3ff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Truncate the file if necessary. */
- if(filesize < get_file_size(filename))
- {
- file = fopen(filename, "rb+");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", filename);
- return;
- }
- ftruncate(fileno(file), filesize);
- fclose(file);
- }
- }
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Get the file name. */
- char filename[13];
- strncpy(filename, (char *)(cur + 0x10), 12);
- filename[12] = '\0';
- /* Get the file size. */
- int filesize = cur[0x1c] | (cur[0x1d] << 8);
- /* Go to the first block of the file. */
- int block = cur[2] | (cur[3] << 8);
- /* Create the file. */
- FILE *file = fopen(filename, "wb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not create file: %s\n", filename);
- continue;
- }
- /* Write the file data. */
- while(block != 0xffff)
- {
- /* Go to the block data. */
- cur = mcdata + block * 0x1000;
- /* Write the block data to the file. */
- if(fwrite(cur, 1, 0x1000, file) != 0x1000)
- {
- fprintf(stderr, "Error: Could not write to file: %s\n", filename);
- fclose(file);
- remove(filename);
- return;
- }
- /* Get the next block. */
- block = cur[0xffe] | (cur[0xfff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Truncate the file if necessary. */
- if(filesize < get_file_size(filename))
- {
- file = fopen(filename, "rb+");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", filename);
- return;
- }
- ftruncate(fileno(file), filesize);
- fclose(file);
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* This function extracts a file from the memory
- card. */
- void extract_file(char *file)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is the file we're looking for. */
- if(strncmp(file, (char *)(cur + 0x10), 12) == 0)
- {
- /* Get the file size. */
- int filesize = cur[0x1c] | (cur[0x1d] << 8);
- /* Go to the first block of the file. */
- int block = cur[2] | (cur[3] << 8);
- /* Create the file. */
- FILE *file = fopen(file, "wb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not create file: %s\n", file);
- return;
- }
- /* Write the file data. */
- while(block != 0xffff)
- {
- /* Go to the block data. */
- cur = mcdata + block * 0x2000;
- /* Write the block data to the file. */
- if(fwrite(cur, 1, 0x2000, file) != 0x2000)
- {
- fprintf(stderr, "Error: Could not write to file: %s\n", file);
- fclose(file);
- remove(file);
- return;
- }
- /* Get the next block. */
- block = cur[0x1fe] | (cur[0x1ff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Trunc
- return;
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* If we get here, the file was not found in MCR format. */
- fprintf(stderr, "Error: File not found: %s\n", file);
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is the file we're looking for. */
- if(strncmp(file, (char *)(cur + 0x10), 12) == 0)
- {
- /* Get the file size. */
- int filesize = cur[0x1c] | (cur[0x1d] << 8);
- /* Go to the first block of the file. */
- int block = cur[2] | (cur[3] << 8);
- /* Create the file. */
- FILE *file = fopen(file, "wb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not create file: %s\n", file);
- return;
- }
- /* Write the file data. */
- while(block != 0xffff)
- {
- /* Go to the block data. */
- cur = mcdata + block * 0x1000;
- /* Write the block data to the file. */
- if(fwrite(cur, 1, 0x1000, file) != 0x1000)
- {
- fprintf(stderr, "Error: Could not write to file: %s\n", file);
- fclose(file);
- remove(file);
- return;
- }
- /* Get the next block. */
- block = cur[0xffe] | (cur[0xfff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Truncate the file if necessary. */
- if(filesize < get_file_size(file))
- {
- file = fopen(file, "rb+");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", file);
- return;
- }
- ftruncate(fileno(file), filesize);
- fclose(file);
- }
- return;
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* If we get here, the file was not found in GME format. */
- fprintf(stderr, "Error: File not found: %s\n", file);
- }
- }
- /* This function extracts all files that match a specified pattern.
- card. */
- void extract_pattern(char *pattern)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is a file that matches the pattern. */
- char filename[13];
- strncpy(filename, (char *)(cur + 0x10), 12);
- filename[12] = '\0';
- if(match(pattern, filename))
- {
- /* Get the file size. */
- int filesize = cur[0x1c] | (cur[0x1d] << 8);
- /* Go to the first block of the file. */
- int block = cur[2] | (cur[3] << 8);
- /* Create the file. */
- FILE *file = fopen(filename, "wb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not create file: %s\n", filename);
- continue;
- }
- /* Write the file data. */
- while(block != 0xffff)
- {
- /* Go to the block data. */
- cur = mcdata + block * 0x2000;
- /* Write the block data to the file. */
- if(
- fclose(file);
- remove(filename);
- return;
- }
- /* Get the next block. */
- block = cur[0x1fe] | (cur[0x1ff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Truncate the file if necessary. */
- if(filesize < get_file_size(filename))
- {
- file = fopen(filename, "rb+");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", filename);
- return;
- }
- ftruncate(fileno(file), filesize);
- fclose(file);
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is a file that matches the pattern. */
- char filename[13];
- strncpy(filename, (char *)(cur + 0x10), 12);
- filename[12] = '\0';
- if(match(pattern, filename))
- {
- /* Get the file size. */
- /* Get the next block. */
- block = cur[0xffe] | (cur[0xfff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Truncate the file if necessary. */
- if(filesize < get_file_size(filename))
- {
- file = fopen(filename, "rb+");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", filename);
- return;
- }
- ftruncate(fileno(file), filesize);
- fclose(file);
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- }
- /* This function copies a file from the computer to the memory card. */
- void copy_to_card(char *file)
- {
- /* Check if the file exists. */
- if(get_file_size(file) == -1)
- {
- fprintf(stderr, "Error: File not found: %s\n", file);
- return;
- }
- /* Check if the memory card is full. */
- if(get_free_blocks() == 0)
- {
- fprintf(stderr, "Error: Memory card is full.\n");
- return;
- }
- /* Open the file. */
- FILE *infile = fopen(file, "rb");
- if(infile == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", file);
- return;
- }
- /* Read the file data. */
- int filesize = get_file_size(file);
- char *data = (char *)malloc(filesize);
- if(data == NULL)
- {
- fprintf(stderr, "Error: Out of memory.\n");
- fclose(infile);
- return;
- }
- if(fread(data, 1, filesize, infile) != filesize)
- {
- fprintf(stderr, "Error: Could not read file: %s\n", file);
- fclose(infile);
- free(data);
- return;
- }
- /* Close the file. */
- fclose(infile);
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is empty. */
- if(cur[0] == 0x00 && cur[1] == 0x00)
- {
- /* Get the file name. */
- char filename[13];
- strncpy(filename, file, 12);
- filename[12] = '\0';
- /* Write the file name to the directory entry. */
- memset(cur + 0x10, ' ', 12);
- strncpy((char *)(cur + 0x10), filename, strlen(filename));
- /* Write the file size
- return;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* If we get here, the memory card is full. */
- fprintf(stderr, "Error: Memory card is full.\n");
- }
- /* This function copies a file from the memory card to the computer. */
- void copy_from_card(char *file)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is the file we're looking for. */
- if(strncmp(file, (char *)(cur + 0x10), 12) == 0)
- {
- /* Get the file size. */
- int filesize = cur[0x1c] | (cur[0x1d] << 8);
- /* Go to the first block of the file. */
- int block = cur[2] | (cur[3] << 8);
- /* Create the file. */
- FILE *file = fopen(file, "wb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not create file: %s\n", file);
- return;
- }
- /* Write the file data. */
- while(block != 0xffff)
- {
- /* Go to the block data. */
- cur = mcdata + block * 0x2000;
- /* Write the block data to the file. */
- if(fwrite(cur, 1, 0x2000, file) != 0x2000)
- {
- fprintf(stderr, "Error: Could not write to file: %s\n", file);
- fclose(file);
- remove(file);
- return;
- }
- /* Get the next block. */
- block = cur[0x1fe] | (cur[0x1ff] << 8);
- }
- /* Close the file. */
- fclose(file);
- /* Truncate the file if necessary. */
- if(filesize < get_file_size(file))
- {
- file = fopen(file, "rb+");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", file);
- return;
- }
- ftruncate(fileno(file), filesize);
- fclose(file);
- }
- return;
- }
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* If we get here, the file was not found in MCR format. */
- fprintf(stderr, "}
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* If we get here, the file was not found in GME format. */
- fprintf(stderr, "Error: File not found: %s\n", file);
- }
- }
- /* This function deletes a file from the memory card. */
- void delete_file(char *file)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Check if this is the file we're looking for. */
- if(strncmp(file, (char *)(cur + 0x10), 12) == 0)
- {
- /* Get the first block of the file. */
- int block = cur[2] | (cur[3] << 8);
- /* Delete the file data. */
- while(block != 0xffff)
- {
- /* Go to the block data. */
- cur = mcdata + block * 0x2000;
- /* Get the next block. */
- int next = cur[0x1fe] | (cur[0x1ff] << 8);
- /* Mark the block as free. */
- cur[0x1fe] = 0x00;
- cur[0x1ff] = 0x00;
- /* Go to the next block. */
- block = next;
- }
- /* Mark the directory entry as free. */
- cur[0] = 0x00;
- cur[1] = 0x00;
- return;
- }
- }
- /* Go to the next directory entry. */
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* If we get here, the file was not found in GME format. */
- fprintf(stderr, "Error: File not found: %s\n", file);
- }
- }
- /* This function prints the contents of a memory card. */
- void print_card_contents()
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Print the header. */
- printf("%-12s %-4s %-4s %-4s\n", "Filename", "Type", "Size", "Free");
- printf("----------------------------------------\n");
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Get the file name. */
- char filename[13];
- strncpy(filename, (char *)(cur + 0x10), 12);
- filename[12] = '\0';
- /* Get the file type. */
- char filetype[5];
- strncpy(filetype, (char *)(cur + 0x1a), 4);
- filetype[4] = '\0';
- /* Get the file size. */
- int filesize = cur[0x1c] | (cur[0x1d] << 8);
- /* Print the directory entry. */
- printf("%-12s %-4s %-4d %-4d\n", filename, filetype, filesize, get_free_blocks());
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Print the header. */
- printf("%-12s %-4s %-4s %-4s\n", "Filename", "Type", "Size", "Free");
- printf("----------------------------------------\n");
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is for a file. */
- if(cur[0] == 0xff && cur[1] == 0xff)
- {
- /* Get the file name. */
- char filename[13];
- strncpy(filename, (char *)(cur + 0x10), 12);
- filename[12] = '\0';
- /* Get the file type. */
- char filetype[5];
- strncpy(filetype, (char *)(cur + 0x1a), 4);
- filetype[4] = '\0';
- /* Print the directory entry. */
- printf("%-12s %-4s %-4d %-4d\n", filename, filetype, filesize, get_free_blocks());
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- }
- }
- /* This function formats a memory card. */
- void format_card()
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Mark each directory entry as free. */
- for(int i = 0; i < 128; i++)
- {
- cur[0] = 0x00;
- cur[1] = 0x00;
- cur += 0x20;
- }
- /* Go to the first block of the memory card. */
- cur = mcdata + 0x4000;
- /* Mark each block as free. */
- for(int i = 0; i < 480; i++)
- {
- cur[0x1fe] = 0x00;
- cur[0x1ff] = 0x00;
- cur += 0x2000;
- }
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Mark each directory entry as free. */
- for(
- cur[0] = 0x00;
- cur[1] = 0x00;
- cur += 0x20;
- }
- /* Go to the first block of the memory card. */
- cur = mcdata + 0x2000;
- /* Mark each block as free. */
- for(int i = 0; i < 240; i++)
- {
- cur[0xffe] = 0x00;
- cur[0xfff] = 0x00;
- cur += 0x1000;
- }
- }
- }
- /* This function saves a memory card file. */
- void save_card(char *filename)
- {
- /* Open the file. */
- FILE *file = fopen(filename, "wb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not create file: %s\n", filename);
- return;
- }
- /* Write the file data. */
- if(fwrite(mcdata, 1, 8192, file) != 8192)
- {
- fprintf(stderr, "Error: Could not write to file: %s\n", filename);
- fclose(file);
- remove(filename);
- return;
- }
- /* Close the file. */
- fclose(file);
- }
- /* This function loads a memory card file. */
- void load_card(char *filename)
- {
- /* Check if the file exists. */
- if(get_file_size(filename) == -1)
- {
- fprintf(stderr, "Error: File not found: %s\n", filename);
- return;
- /* Open the file. */
- FILE *file = fopen(filename, "rb");
- if(file == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", filename);
- return;
- }
- /* Read the file data. */
- if(fread(mcdata, 1, 8192, file) != 8192)
- {
- fprintf(stderr, "Error: Could not read from file: %s\n", filename);
- fclose(file);
- return;
- }
- /* Close the file. */
- fclose(file);
- /* Check if the file is in MCR or GME format. */
- if(mcdata[0] == 'M' && mcdata[1] == 'C')
- {
- inputformat = MCR;
- }
- else if(mcdata[0] == 'M' && mcdata[1] == 'E')
- {
- inputformat = GME;
- }
- else
- {
- fprintf(stderr, "Error: Unrecognized file format: %s\n", filename);
- return;
- }
- }
- /* This function prints the help message. */
- void print_help()
- {
- printf("Usage: psxmc [options] [command] [arguments]\n");
- printf("\n");
- printf("Options:\n");
- printf(" -h, --help Print this help message.\n");
- printf(" -v, --version Print the version number.\n");
- printf("\n");
- printf("Commands:\n");
- printf(" copy-to-card <file> Copy a file to the memory card.\n");
- printf(" copy-from-card <file> Copy a file from the memory card.\n");
- printf(" delete <file> Delete a file from the memory card.\n");
- printf(" ls List the contents of the memory card.\n");
- printf(" format Format the memory card.\n");
- printf(" save <file> Save the memory card.\n");
- printf(" load <file> Load a memory card.\n");
- printf("\n");
- printf("Examples:\n");
- printf(" psxmc copy-to-card myfile.txt\n");
- printf(" psxmc copy-from-card myfile.txt\n");
- printf(" psxmc delete myfile.txt\n");
- printf(" psxmc ls\n");
- printf(" psxmc format\n");
- printf(" psxmc save mycard.mcr\n");
- printf(" psxmc load mycard.mcr\n");
- }
- /* This is the main function. */
- int main(int argc, char *argv[])
- {
- /* Check if the user requested the version number. */
- if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version
- return 0;
- }
- /* Check if the user requested the help message. */
- if(argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0))
- {
- print_help();
- return 0;
- }
- /* Check if the user provided the right number of arguments. */
- if(argc < 2)
- {
- fprintf(stderr, "Error: Missing command.\n");
- return 1;
- }
- /* Parse the command. */
- if(strcmp(argv[1], "copy-to-card") == 0)
- {
- if(argc < 3)
- {
- fprintf(stderr, "Error: Missing argument.\n");
- return 1;
- }
- copy_to_card(argv[2]);
- }
- else if(strcmp(argv[1], "copy-from-card") == 0)
- {
- if(argc < 3)
- {
- fprintf(stderr, "Error: Missing argument.\n");
- return 1;
- }
- copy_from_card(argv[2]);
- }
- else if(strcmp(argv[1], "delete") == 0)
- {
- if(argc < 3)
- {
- fprintf(stderr, "Error: Missing argument.\n");
- return 1;
- }
- delete_file(argv[2]);
- }
- else if(strcmp(argv[1], "ls") == 0)
- {
- if(argc > 2)
- {
- fprintf(stderr, "Error: Unexpected argument.\n");
- return 1;
- }
- print_card_contents();
- }
- else if(strcmp(argv[1], "format") == 0)
- {
- if(argc > 2)
- {
- fprintf(stderr, "Error: Unexpected argument.\n");
- return 1;
- }
- format_card();
- }
- else if(strcmp(argv[1], "save") == 0)
- {
- if(argc < 3)
- {
- fprintf(stderr, "Error: Missing argument.\n");
- return 1;
- }
- save_card(argv[2]);
- }
- else if(strcmp(argv[1], "load") == 0)
- {
- if(argc < 3)
- {
- fprintf(stderr, "Error: Missing argument.\n");
- return 1;
- }
- load_card(argv[2]);
- }
- else
- {
- fprintf(stderr, "Error: Unrecognized command: %s\n", argv[1]);
- return 1;
- }
- return 0;
- }
- return 0;
- }
- /* This function copies a file to a memory card. */
- void copy_to_card(char *file)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the entry is free. */
- if(cur[0] == 0x00 && cur[1] == 0x00)
- {
- /* Open the file. */
- FILE *input = fopen(file, "rb");
- if(input == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", file);
- return;
- }
- /* Get the file size. */
- int filesize = get_file_size(file);
- /* Check if the file is too big. */
- if(filesize > 65535)
- {
- fprintf(stderr, "Error: File too big: %s\n", file);
- fclose(input);
- return;
- }
- /* Check if there is enough free space. */
- if(filesize > get_free_blocks() * 16)
- {
- fprintf(stderr, "Error: Not enough free space.\n");
- fclose(input);
- return;
- }
- /* Get the file name. */
- char filename[13];
- strncpy(filename, get_file_name(file), 12);
- filename[12] = '\0';
- /* Get the file type. */
- char filetype[5];
- strncpy(filetype, get_file_ext(file), 4);
- filetype[4] = '\0';
- /* Write the directory entry. */
- strncpy((char *)(
- cur[0x17] = 0x00;
- cur[0x18] = 0x00;
- cur[0x19] = 0x00;
- cur[0x1a] = 0x00;
- cur[0x1b] = 0x00;
- cur[0x1c] = 0x00;
- cur[0x1d] = 0x00;
- cur[0x1e] = 0x00;
- cur[0x1f] = 0x00;
- /* Go to the first block of the memory card. */
- cur = mcdata + 0x4000;
- /* Find the first free block. */
- while(cur[0x1fe] != 0x00 || cur[0x1ff] != 0x00)
- {
- cur += 0x2000;
- }
- /* Write the file data. */
- int written = 0;
- while(written < filesize)
- {
- int block = fread(cur, 1, 0x2000, input);
- written += block;
- cur += 0x2000;
- }
- /* Pad the last block with zeros. */
- for(int i = written; i < 0x2000; i++)
- {
- cur[i] = 0x00;
- }
- /* Close the file. */
- fclose(input);
- /* Print a success message. */
- printf("File copied: %s\n", filename);
- return;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* Print an error message. */
- fprintf(stderr, "Error: No free directory entries.\n");
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 16; i++)
- {
- /* Check if the entry is free. */
- if(cur[0] == 0x00 && cur[1] == 0x00)
- {
- /* Open the file. */
- FILE *input = fopen(file, "rb");
- if(input == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", file);
- return;
- }
- /* Get the file size. */
- int filesize = get_file_size(file);
- /* Check if the file is too big. */
- if(filesize > 65535)
- {
- fprintf(stderr, "Error: File too big: %s\n", file);
- fclose(input);
- return;
- }
- /* Check if there is enough free space. */
- if(filesize > get_free_blocks() * 8)
- {
- fprintf(stderr, "Error: Not enough free space.\n
- cur[0x17] = 0x00;
- cur[0x18] = 0x00;
- cur[0x19] = 0x00;
- cur[0x1a] = 0x00;
- cur[0x1b] = 0x00;
- cur[0x1c] = 0x00;
- cur[0x1d] = 0x00;
- cur[0x1e] = 0x00;
- cur[0x1f] = 0x00;
- /* Go to the first block of the memory card. */
- cur = mcdata + 0x2000;
- /* Find the first free block. */
- while(cur[0x1fe] != 0x00 || cur[0x1ff] != 0x00)
- {
- cur += 0x1000;
- }
- /* Write the file data. */
- int written = 0;
- while(written < filesize)
- {
- int block = fread(cur, 1, 0x1000, input);
- written += block;
- cur += 0x1000;
- }
- /* Pad the last block with zeros. */
- for(int i = written; i < 0x1000; i++)
- {
- cur[i] = 0x00;
- }
- /* Close the file. */
- fclose(input);
- /* Print a success message. */
- printf("File copied: %s\n", filename);
- return;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* Print an error message. */
- fprintf(stderr, "Error: No free directory entries.\n");
- }
- }
- /* This function copies a file from a memory card. */
- void copy_from_card(char *file)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the file is found. */
- if(strncmp((char *)(cur + 0x09), file, 12) == 0)
- {
- /* Open the file. */
- FILE *output = fopen(file, "wb");
- if(output == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", file);
- return;
- }
- /* Go to the first block of the memory card. */
- cur = mcdata + 0x4000;
- /* Read the file data. */
- int filesize = (cur[0x01ff] << 8) | cur[0x01fe];
- int blocks = (filesize + 0x1ff) / 0x200;
- for(int i = 0; i < blocks; i++)
- {
- fwrite(cur, 1, 0x200, output);
- cur += 0x200;
- }
- /* Close the file. */
- fclose(output
- /* Print a success message. */
- printf("File copied: %s\n", file);
- return;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* Print an error message. */
- fprintf(stderr, "Error: File not found: %s\n", file);
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 16; i++)
- {
- /* Check if the file is found. */
- if(strncmp((char *)(cur + 0x09), file, 12) == 0)
- {
- /* Open the file. */
- FILE *output = fopen(file, "wb");
- if(output == NULL)
- {
- fprintf(stderr, "Error: Could not open file: %s\n", file);
- return;
- }
- /* Go to the first block of the memory card. */
- cur = mcdata + 0x2000;
- /* Read the file data. */
- int filesize = (cur[0x0ff] << 8) | cur[0x0fe];
- int blocks = (filesize + 0xff) / 0x100;
- for(int i = 0; i < blocks; i++)
- {
- fwrite(cur, 1, 0x100, output);
- cur += 0x100;
- }
- /* Close the file. */
- fclose(output);
- /* Print a success message. */
- printf("File copied: %s\n", file);
- return;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* Print an error message. */
- fprintf(stderr, "Error: File not found: %s\n", file);
- }
- }
- /* This function deletes a file from a memory card. */
- void delete_file(char *file)
- {
- /* Check if the file is available in MCR format. */
- if(inputformat == MCR)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x2000;
- /* Check each directory entry. */
- for(int i = 0; i < 128; i++)
- {
- /* Check if the file is found. */
- if(strncmp((char *)(cur + 0x09), file, 12) == 0)
- {
- /* Clear the directory entry. */
- cur[0x00] = 0x00;
- cur[0x01] = 0x00;
- cur[0x02] = 0x00;
- cur[0x03] = 0x00;
- cur[0x04] = 0x00;
- cur[0x05] = 0x00;
- /* Clear the file blocks. */
- int blocks = (filesize + 0x1ff) / 0x200;
- for(int i = 0; i < blocks; i++)
- {
- cur[0xfe] = 0x00;
- cur[0xff] = 0x00;
- cur += 0x200;
- }
- /* Print a success message. */
- printf("File deleted: %s\n", file);
- return;
- }
- /* Go to the next directory entry. */
- cur += 0x20;
- }
- /* Print an error message. */
- fprintf(stderr, "Error: File not found: %s\n", file);
- }
- /* Check if the file is available in GME format. */
- else if(inputformat == GME)
- {
- /* Go to the directory section of the memory card. */
- cur = mcdata + 0x1e00;
- /* Check each directory entry. */
- for(int i = 0; i < 16; i++)
- {
- /* Check if the file is found. */
- if(strncmp((char *)(cur + 0x09), file, 12) == 0)
- {
- /* Clear the directory entry. */
- cur[0x00] = 0x00;
- cur[0x01] = 0x00;
- cur[0x02] = 0x00;
- cur[0x03] = 0x00;
- cur[0x04] = 0x00;
- cur[0x05] = 0x00;
- cur[0x06] = 0x00;
- cur[0x07] = 0x00;
- cur[0x08] = 0x00;
- cur[0x09] = 0x00;
- cur[0x0a] = 0x00;
- cur[0x0b] = 0x00;
- cur[0x0c] = 0x00;
- cur[0x0d] = 0x00;
- cur[0x0e] = 0x00;
- cur[0x0f] = 0x00;
- cur[0x10] = 0x00;
- cur[0x11] = 0x00;
- cur[0x12] = 0x00;
- cur[0x13] = 0x00;
- cur[0x14] = 0x00;
- cur[0x15] = 0x00;
- cur[0x16] = 0x00;
- cur[0x17] = 0x00;
- cur[0x18] = 0x00;
- cur[0x19] = 0x00;
- cur[0x1a] = 0x00;
- cur[0x1b] = 0x00;
- cur[0x1c] = 0x00;
- cur[0x1d] = 0x00;
Advertisement
Add Comment
Please, Sign In to add comment