#include #include #include /** * Size of the read buffer (to be allocated with @c malloc()) */ #define READ_BUFFER_SIZE (4*1024*1024) int main(int argc, char** argv) { FILE* in = NULL; /* Input file */ FILE* out = NULL; /* Output file */ uint8_t* buf = NULL; /* Read buffer */ uint64_t bytes_to_copy = 0; /* How many bytes we are to copy */ uint32_t id[3]; /* Nero footer */ size_t read; /* Number of bytes read */ size_t to_read; /* Number of bytes to read in the loop */ size_t written; /* Number of bytes written */ int exit_code = EXIT_SUCCESS; /* Exit code */ if (3 != argc) { printf("Usage: nrg2iso nrgfile isofile\n"); return EXIT_FAILURE; } in = fopen(argv[1], "rb"); if (NULL == in) { printf("Failed to open file '%s' for reading\n", argv[1]); return EXIT_FAILURE; } out = fopen(argv[2], "wb"); if (NULL == out) { fclose(in); printf("Failed to create file '%s'\n", argv[2]); return EXIT_FAILURE; } buf = malloc(READ_BUFFER_SIZE); if (NULL == buf) { fclose(in); fclose(out); printf("Failed to allocate %lu bytes of memory\n", (unsigned long)READ_BUFFER_SIZE); return EXIT_FAILURE; } fseek(in, -sizeof(id), SEEK_END); read = fread(&id, 1, sizeof(id), in); if (read != sizeof(id)) { fclose(in); fclose(out); printf("Read error (read: %u, needed: %u)\n", read, sizeof(id)); return EXIT_FAILURE; } if (0x3552454Eul == id[0]) { /* Nero v2 footer */ id[1] = ((id[1] & 0x000000FF) << 24) | ((id[1] & 0x0000FF00) << 8) | ((id[1] & 0x00FF0000) >> 8) | ((id[1] & 0xFF000000) >> 24); id[2] = ((id[2] & 0x000000FF) << 24) | ((id[2] & 0x0000FF00) << 8) | ((id[2] & 0x00FF0000) >> 8) | ((id[2] & 0xFF000000) >> 24); bytes_to_copy = id[2] | ((uint64_t)(id[1]) << 32); } else if (0x4F52454E == id[1]) { /* Nero v1 footer */ bytes_to_copy = id[2]; bytes_to_copy = ((bytes_to_copy & 0x000000FF) << 24) | ((bytes_to_copy & 0x0000FF00) << 8) | ((bytes_to_copy & 0x00FF0000) >> 8) | ((bytes_to_copy & 0xFF000000) >> 24); } else { fclose(in); fclose(out); free(buf); printf("Not a Nero image\n"); return EXIT_FAILURE; } bytes_to_copy -= 512*600; fseek(in, 512*600, SEEK_SET); while (bytes_to_copy > 0) { to_read = (bytes_to_copy < READ_BUFFER_SIZE) ? bytes_to_copy : READ_BUFFER_SIZE; read = fread(buf, 1, to_read, in); if (0 == read) { exit_code = EXIT_FAILURE; printf("\n\nPhysical EOF before logical EOF on '%s'\n", argv[1]); break; } written = fwrite(buf, 1, read, out); if (written != read) { exit_code = EXIT_FAILURE; printf("\n\nWrite error\n"); break; } bytes_to_copy -= read; printf("."); } if (EXIT_SUCCESS == exit_code) { printf("\n\nSuccess!\n"); } fclose(in); fclose(out); free(buf); return exit_code; }