FAT32 hackings in 2004!
Of course not! Here is the story first: Behnam sent me back my tiny Minolta DimageX digital camera, but forgot to send the USB cable. So I had 128MB of space in my SD Card to fill with photos, and then wait for the cable to arrive by the next carrier from Tehran ;-). So, with Siamak, we made some 160 great photos, of meeting with Toronto Dylanists, in Toronto Wonderland, Niagara Falls region, and a few other places. I ran out of memory a few times, and each time I went back and removed a few redundant or bad photos, to make more space. After dropping Siamak at the airport, I was getting back home when in the subway, a bit bored, I was playing with the camera when I formatted the SD Card with all the photos inside!
I was sure that it just "quick format"ted it, can't empty 128MB in 2 seconds. My heart was in my mouth. I went straight to Future Shop and bought a USB SD Card reader, came home, copied the whole partition image. God, you mean I have to go back to 1995 and unformat/undelete the files, or worse, run Norton diskedit, or even worse, recover my photos by reading FAT32 chains manually?!?!?!
I made a guess that this dumb camera just writes the files sequentially all the time, no fill-in-the-gaps I mean. Well, thinking a bit more you see that you don't need to make any assumptions for that. The usage pattern has been all writes, with 5 batches of removes. So at most 10 images can be hurt. I proceeded and did that, I first copied an old photo taken by the same camera, and the typed these on command line:
# dd if=/dev/sdb of=sdcard
# head -c 100 pict0680.jpg > header
# python
Python 2.3.3 (#1, May 7 2004, 10:31:40)
[GCC 3.3.3 20040412 (Red Hat Linux 3.3.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> sdcard=file("sdcard", "rb").read()
>>> header=file("header", "rb").read()
>>> header
'\xff\xd8\xff\xe1$EExif'
>>> import string
>>> jpgs = string.split(sdcard, header)
>>> len(jpgs)
164
>>> jpgs=[header+x for x in jpgs]
>>> c=0
>>> for jpg in jpgs:
... c += 1
... f = open(str(c)+".jpg", "wb")
... f.write(jpg)
... f.close()
...
>>> ^D
# ls
100.jpg 118.jpg 136.jpg 153.jpg 21.jpg 39.jpg 56.jpg 73.jpg 90.jpg
101.jpg 119.jpg 137.jpg 154.jpg 22.jpg 3.jpg 57.jpg 74.jpg 91.jpg
102.jpg 11.jpg 138.jpg 155.jpg 23.jpg 40.jpg 58.jpg 75.jpg 92.jpg
103.jpg 120.jpg 139.jpg 156.jpg 24.jpg 41.jpg 59.jpg 76.jpg 93.jpg
104.jpg 121.jpg 13.jpg 157.jpg 25.jpg 42.jpg 5.jpg 77.jpg 94.jpg
105.jpg 122.jpg 140.jpg 158.jpg 26.jpg 43.jpg 60.jpg 78.jpg 95.jpg
106.jpg 123.jpg 141.jpg 159.jpg 27.jpg 44.jpg 61.jpg 79.jpg 96.jpg
107.jpg 124.jpg 142.jpg 15.jpg 28.jpg 45.jpg 62.jpg 7.jpg 97.jpg
108.jpg 125.jpg 143.jpg 160.jpg 29.jpg 46.jpg 63.jpg 80.jpg 98.jpg
109.jpg 126.jpg 144.jpg 161.jpg 2.jpg 47.jpg 64.jpg 81.jpg 99.jpg
10.jpg 127.jpg 145.jpg 162.jpg 30.jpg 48.jpg 65.jpg 82.jpg 9.jpg
110.jpg 128.jpg 146.jpg 163.jpg 31.jpg 49.jpg 66.jpg 83.jpg header
111.jpg 129.jpg 147.jpg 164.jpg 32.jpg 4.jpg 67.jpg 84.jpg sdcard
112.jpg 12.jpg 148.jpg 165.jpg 33.jpg 50.jpg 68.jpg 85.jpg
113.jpg 130.jpg 149.jpg 16.jpg 34.jpg 51.jpg 69.jpg 86.jpg
114.jpg 131.jpg 14.jpg 17.jpg 35.jpg 52.jpg 6.jpg 87.jpg
115.jpg 132.jpg 150.jpg 18.jpg 36.jpg 53.jpg 70.jpg 88.jpg
116.jpg 133.jpg 151.jpg 19.jpg 37.jpg 54.jpg 71.jpg 89.jpg
117.jpg 134.jpg 152.jpg 20.jpg 38.jpg 55.jpg 72.jpg 8.jpg
Voila! And guess what? All photos are correct except for exactly 10! It really doesn't make sense to go about FAT32 hacking anymore. But I know where to find the missing bits...
Here is a proof of recovery: