I tried to implement recover through the simplest and shortest way I could imagine.
The code compiles and saves 50 JPGs with proper names, but when I open them, all of them are just empty and even ls -l
shows that the files have 0B.
Also I tried debugging using printf
and I found that each file is missing 1 block.
I checked online and found that each file should have either 19 or 20 blocks, but my files have 18 or 19 blocks.
I couldn't figure out why the files are empty or why I have been missing 1 block.
Here's the code:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define block_size 512
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover card\n");
return 1;
}
FILE *card = fopen(argv[1], "r");
if (card == NULL)
{
printf("%s: could not open\n", argv[1]);
return 2;
}
FILE *jpg = NULL;
BYTE buffer[block_size];
int jpg_count = 0;
// 7 characters for name + 1 character for null
char jpg_name[8] = {0};
// To check no. of blocks for each jpg
int write_count = 0;
// Iterate through the card
while (fread(&buffer, 1, block_size, card) == block_size)
{
// Check for start of jpg
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff
&& (buffer[3] & 0xf0)== 0xe0)
{
// If found start close previous jpg if availabe
if (jpg != NULL)
{
fclose(jpg);
printf("\n");
}
// Reset w_count for new jpg
write_count = 0;
// Create new jpg
sprintf(jpg_name, "%03i.jpg",jpg_count++);
// Print jpg name for testing
printf("%s: ", jpg_name);
jpg = fopen(jpg_name, "w");
if (jpg == NULL)
{
printf("error\n");
fclose(jpg);
}
}
// The first if and this if are not mutually exclusive
// if jpg exists keep writing until EOF or next JPEG found(above condition)
if (jpg_count > 0 && jpg != NULL)
{
fwrite(&buffer, 1, block_size, card);
printf("%i ", write_count++);
}
}
printf("\n");
// Close last jpg
fclose(jpg);
fclose(card);
return 0;
}