A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 182 lines 5.9 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * 9 * Copyright (C) 2013 Lorenzo Miori 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 2 14 * of the License, or (at your option) any later version. 15 * 16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 17 * KIND, either express or implied. 18 * 19 ****************************************************************************/ 20 21#include <stdio.h> 22#include <string.h> 23#include <stdlib.h> 24#include <stdarg.h> 25#include <getopt.h> 26#include <stdint.h> 27#include "common.h" 28 29static char* input_dir = NULL; 30static FILE* output_file = NULL; 31static struct firmware_data fw; 32 33static void cleanup(void) 34{ 35 for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++) 36 { 37 free(fw.component_data[i]); 38 } 39} 40 41static void die(int error) 42{ 43 if (output_file != NULL) 44 fclose(output_file); 45 free(input_dir); 46 cleanup(); 47 exit(error); 48} 49 50static void pad4byte(char byte, FILE* handle) { 51 int padding = 4 - ftell(handle) % 4; 52 if (padding != 4) { 53 while (padding-- > 0) { 54 fwrite(&byte, 1, 1, handle); 55 } 56 } 57} 58 59int main(int argc, char **argv) 60{ 61 FILE* component_handle = NULL; 62 FILE* rev_info_file = NULL; 63 int error = 0; 64 char* tmp_path = malloc(MAX_PATH); 65 66 memset(&fw, 0, sizeof(fw)); 67 68 if (argc < 2) 69 { 70 printf( 71 "Crypts Samsung YP-R0/YP-R1 ROM file format\n" 72 "Usage: fwcrypt <output ROM file path\n" 73 ); 74 return 1; 75 } 76 77 input_dir = malloc(MAX_PATH); 78 input_dir[0] = '\0'; 79 if (argc > 2) 80 { 81 strcpy(input_dir, argv[2]); 82 } 83 84 /* open the output file for write */ 85 output_file = fopen(argv[1], "wb"); 86 if (output_file == NULL) 87 { 88 fprintf(stderr, "Cannot open file for writing: %m\n"); 89 die(SAMSUNG_WRITE_ERROR); 90 } 91 92 /* write generic header */ 93 join_path(tmp_path, input_dir, "RevisionInfo.txt"); 94 rev_info_file = fopen(tmp_path, "rb"); 95 if (rev_info_file != NULL) 96 { 97 for (int i = 0; i < GENERIC_HEADER_LINES; i++) 98 { 99 char header[MAX_HEADER_LEN]; 100 error += fgets(header, MAX_HEADER_LEN, rev_info_file) == NULL; 101 error += fprintf(output_file, "%s", header) != (signed)strlen(header); 102 } 103 fclose(rev_info_file); 104 } 105 else 106 { 107 /* write some generic information */ 108 error += fprintf(output_file, YPR0_VERSION) != strlen(YPR0_VERSION); 109 error += fprintf(output_file, YPR0_TARGET) != strlen(YPR0_TARGET); 110 error += fprintf(output_file, YPR0_USER) != strlen(YPR0_USER); 111 error += fprintf(output_file, YPR0_DIR) != strlen(YPR0_DIR); 112 error += fprintf(output_file, YPR0_TIME) != strlen(YPR0_TIME); 113 } 114 115 if(error != 0) 116 { 117 fprintf(stderr, "Cannot write generic header\n"); 118 die(SAMSUNG_WRITE_ERROR); 119 } 120 121 for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++) 122 { 123 join_path(tmp_path, input_dir, firmware_filenames[i]); 124 component_handle = fopen(tmp_path, "rb"); 125 if (component_handle == NULL) 126 { 127 fprintf(stderr, "Error while reading firmware component.\n"); 128 die(SAMSUNG_READ_ERROR); 129 } 130 fw.component_size[i] = get_filesize(component_handle); 131 fw.component_data[i] = malloc(fw.component_size[i] * sizeof(char)); 132 fread(fw.component_data[i], sizeof(char), fw.component_size[i], component_handle); 133 fclose(component_handle); 134 135 /* compute checksum */ 136 md5sum(fw.component_checksum[i], fw.component_data[i], fw.component_size[i]); 137 printf("%s : size(%ld),checksum(%s)\n", firmware_components[i], 138 fw.component_size[i], fw.component_checksum[i]); 139 /* write metadata header to file */ 140 if (fprintf(output_file, "%s : size(%ld),checksum(%s)\n", firmware_components[i], 141 fw.component_size[i], fw.component_checksum[i]) < 0) 142 { 143 fprintf(stderr, "Error writing to output file.\n"); 144 die(SAMSUNG_WRITE_ERROR); 145 } 146 } 147 148 /* Padding */ 149 pad4byte('\n', output_file); 150 151 /* write final data to the firmware file */ 152 for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++) 153 { 154 /* the bootloader needs to be patched: add checksum of the components */ 155 if (strcmp("MBoot", firmware_components[i]) == 0) 156 { 157 int index=MBOOT_CHECKSUM_OFFSET; 158 for (int z = 0; z < YPR0_COMPONENTS_COUNT; z++) 159 { 160 index += sprintf(fw.component_data[i] + index, "%ld:%s\n", 161 fw.component_size[z], fw.component_checksum[z]); 162 } 163 } 164 /* crypt data */ 165 cyclic_xor(fw.component_data[i], fw.component_size[i], g_yp_key, sizeof(g_yp_key)); 166 /* write data */ 167 size_t written = fwrite(fw.component_data[i], sizeof(char), 168 fw.component_size[i], output_file); 169 if (written != fw.component_size[i]) 170 { 171 fprintf(stderr, "%s: error writing data to file. Written %ld bytes\n", 172 firmware_components[i], written); 173 die(SAMSUNG_WRITE_ERROR); 174 } 175 /* padding */ 176 if (i < (YPR0_COMPONENTS_COUNT-1)) 177 pad4byte('\0', output_file); 178 } 179 180 /* free the big amount of memory and close handles */ 181 die(SAMSUNG_SUCCESS); 182}