1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS bin2c 4 * FILE: tools/bin2c.c 5 * PURPOSE: Converts a binary file into a byte array 6 * PROGRAMMER: Herm�s B�lusca - Ma�to 7 */ 8 9 #include <stdio.h> 10 11 #ifdef _WIN32 12 #include <string.h> // Required for _stricmp() 13 #else 14 #include <strings.h> // Required for strcasecmp() 15 #define _stricmp strcasecmp 16 #endif 17 18 static size_t dumpHex(FILE* inFile, FILE* outCFile, char nullTerminate) 19 { 20 size_t bufLen = 0; 21 unsigned char ch; 22 23 fprintf(outCFile, "\n{"); 24 do 25 { 26 /* Read the next byte */ 27 ch = fgetc(inFile); 28 29 if (feof(inFile) && nullTerminate) 30 ch = 0x00; 31 32 if (!feof(inFile) || nullTerminate) 33 { 34 /* Start a new line if needed */ 35 if ((bufLen % 16) == 0) 36 fprintf(outCFile, "\n "); 37 38 /* Write the byte or the optional NULL terminator */ 39 fprintf(outCFile, " 0x%02x,", (unsigned int)ch); 40 41 ++bufLen; 42 } 43 } while (!feof(inFile)); 44 fprintf(outCFile, "\n}"); 45 46 return bufLen; 47 } 48 49 static size_t dumpStr(FILE* inFile, FILE* outCFile) 50 { 51 size_t bufLen = 0; 52 unsigned char ch; 53 54 /* Always start the first line */ 55 fprintf(outCFile, "\n \""); 56 do 57 { 58 /* Read the next byte */ 59 ch = fgetc(inFile); 60 61 /* If a byte is available... */ 62 if (!feof(inFile)) 63 { 64 /* ... do we need to start a new line? */ 65 if ((bufLen != 0) && (bufLen % 16) == 0) 66 { 67 /* Yes, end the current line and start a new one */ 68 fprintf(outCFile, "\""); 69 fprintf(outCFile, "\n \""); 70 } 71 72 /* Now write the byte */ 73 fprintf(outCFile, "\\x%02x", (unsigned int)ch); 74 } 75 /* ... otherwise, end the current line... */ 76 else 77 { 78 fprintf(outCFile, "\""); 79 /* We break just after */ 80 } 81 82 ++bufLen; // This takes also the final NULL terminator into account. 83 84 } while (!feof(inFile)); 85 86 return bufLen; 87 } 88 89 static void usage(char* name) 90 { 91 fprintf(stdout, "Usage: %s infile.bin outfile.c outfile.h [BIN|BINSTR|STR] array_name [array_attribute [header_for_attribute]]\n", name); 92 } 93 94 int main(int argc, char* argv[]) 95 { 96 FILE* inFile; 97 FILE* outCFile; 98 FILE* outHFile; 99 size_t bufLen; 100 101 /* Validate the arguments */ 102 if (argc < 6) 103 { 104 usage(argv[0]); 105 return -1; 106 } 107 108 /* Verify the output format */ 109 if (_stricmp(argv[4], "BIN" ) != 0 && 110 _stricmp(argv[4], "BINSTR") != 0 && 111 _stricmp(argv[4], "STR" ) != 0) 112 { 113 usage(argv[0]); 114 return -1; 115 } 116 117 /* Open the input and output files */ 118 inFile = fopen(argv[1], "rb"); 119 if (!inFile) 120 { 121 fprintf(stderr, "ERROR: Couldn't open data file '%s'.\n", argv[1]); 122 return -1; 123 } 124 outCFile = fopen(argv[2], "w"); 125 if (!outCFile) 126 { 127 fclose(inFile); 128 fprintf(stderr, "ERROR: Couldn't create output source file '%s'.\n", argv[2]); 129 return -1; 130 } 131 outHFile = fopen(argv[3], "w"); 132 if (!outHFile) 133 { 134 fclose(outCFile); 135 fclose(inFile); 136 fprintf(stderr, "ERROR: Couldn't create output header file '%s'.\n", argv[3]); 137 return -1; 138 } 139 140 /* Generate the source file and close it */ 141 fprintf(outCFile, "/* This file is autogenerated, do not edit. */\n\n"); 142 if (argc >= 8) 143 { 144 /* Include needed header for defining the array attribute */ 145 fprintf(outCFile, "#include \"%s\"\n", argv[7]); 146 } 147 fprintf(outCFile, "#include \"%s\"\n\n", argv[3]); 148 149 /* Generate the data array */ 150 if (argc >= 7) 151 { 152 /* Add the array attribute */ 153 fprintf(outCFile, "%s ", argv[6]); 154 } 155 fprintf(outCFile, "unsigned char %s[] =", argv[5]); 156 157 /* Output the bytes in the chosen format */ 158 if (_stricmp(argv[4], "BIN") == 0) 159 bufLen = dumpHex(inFile, outCFile, 0); 160 else if (_stricmp(argv[4], "BINSTR") == 0) 161 bufLen = dumpHex(inFile, outCFile, 1); 162 else // (_stricmp(argv[4], "STR") == 0) 163 bufLen = dumpStr(inFile, outCFile); 164 165 fprintf(outCFile, ";\n"); 166 fclose(outCFile); 167 168 /* Generate the header file and close it */ 169 fprintf(outHFile, "/* This file is autogenerated, do not edit. */\n\n"); 170 fprintf(outHFile, "#define %s_SIZE %lu\n" , argv[5], bufLen); 171 fprintf(outHFile, "extern unsigned char %s[%lu];\n", argv[5], bufLen); 172 fclose(outHFile); 173 174 /* Close the input file */ 175 fclose(inFile); 176 177 return 0; 178 } 179 180 /* EOF */ 181