How to Delete a file entry in fat32 directory stracture

Apr 1, 2010 at 11:11am
I want to dele a file from a directory in fat32 formated pendrive. Please tell me the way to do it. I am using fat table to read the directory entry.

Or please tell me the mechanism and changes that occur in a directory entry when a file is deleted from it.

Last edited on Apr 4, 2010 at 11:36am
Apr 1, 2010 at 11:30am

http://www.codeguru.com/cpp/cpp/cpp_mfc/files/article.php/c13907/

http://www.codeguru.com/cpp/cpp/cpp_mfc/files/article.php/c13831/

It's simple. First you have to read file allocation table, and find the file you need. Then replace first character of file name with 0xE5 and write modified file allocation table to disk.
Apr 1, 2010 at 3:36pm
Thank you very much
Apr 1, 2010 at 8:14pm
I used the following code to delete the file

void lastClus(int clusNum)
{
void * ptr;
int nextVal;
char * buffer=(char *)malloc(bytesPerSec);
DWORD bytesread;
int fatOffset,thisFatSecNum,thisFatEntOffset;
fatOffset=clusNum*4;
thisFatSecNum=reservedSecCount+fatOffset/bytesPerSec;
thisFatEntOffset=fatOffset%bytesPerSec;

SetFilePointer (hDevice, thisFatSecNum*bytesPerSec, NULL, FILE_BEGIN);

if (!ReadFile (hDevice, buffer, bytesPerSec, &bytesread, NULL) )
exit(0);

ptr=&buffer[thisFatEntOffset];
nextVal=(*((int *) ptr))& 0x0FFFFFFF;
//printf("\n1 %d\n",nextVal);
if(nextVal!=0x0FFFFFFF)
{
*((DWORD *)&buffer[thisFatEntOffset])=(*((DWORD *) &buffer[thisFatEntOffset])) &0xF0000000;
WriteFile(hDevice, buffer, bytesPerSec, &bytesread, NULL);
lastClus(nextVal);
//*((DWORD *)&buffer[ThisFatEntOffset])=(*((DWORD *) &buffer[ThisFatEntOffset])) &0x0FFFFFFF;



}
if(nextVal==0x0FFFFFFF)
{

*((DWORD *)&buffer[thisFatEntOffset])=(*((DWORD *) &buffer[thisFatEntOffset])) &0xF0000000;
WriteFile(hDevice, buffer, bytesPerSec, &bytesread, NULL);
printf("EOC mark reached\n");
}


/*ptr=&buffer[thisFatEntOffset];
nextVal=(*((int *) ptr))& 0x0FFFFFFF;
printf("\n1 %d\n",nextVal);
*((DWORD *)&buffer[thisFatEntOffset])=(*((DWORD *) &buffer[thisFatEntOffset])) &0xF0000000;
nextVal=(*((int *) ptr))& 0x0FFFFFFF;
printf("\n1 %d\n",nextVal);
*/
}
But its not working. Whats wrong in this. It works but no change occurs in the pendrive. and no files are deleted. why?
Apr 2, 2010 at 4:21am
May be I am not able to write back to the disk. Is there any access problem?????
Apr 2, 2010 at 5:46am
the WriteFile function in not writing on the disk

Is there any special permissions required for writing to the disk??
Apr 2, 2010 at 6:45am
Can you post code that opens the disk? Also, what is your OS?
Apr 2, 2010 at 8:02am
I am using windows vista home premium


void open_drive(char * BUF)
{
//BUF value is \\\\.\\G:
void* ptr;
char* buffer = (char*)malloc (bytesPerSec);
DWORD bytesread;
hDevice = CreateFile(BUF,GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, 0, NULL);

if (hDevice == INVALID_HANDLE_VALUE)
{
printf("This is not working :-(");
printf("\n\n%s\n",BUF);
getchar();
exit(0);
}

SetFilePointer (hDevice, 0, NULL, FILE_BEGIN);

if (!ReadFile (hDevice, buffer, bytesPerSec, &bytesread, NULL) )
exit(0);

ptr=&buffer[11];
bytesPerSec=*((short *)ptr);

secPerClus=buffer[13];

ptr=&buffer[14];
reservedSecCount=*((short *)ptr);

numFats=buffer[16];

mediaType=buffer[21];

ptr=&buffer[32];
totSec=*((int *)ptr);

ptr=&buffer[36];
fatSize=*((int *)ptr);

ptr=&buffer[44];
rootClus=*((int *)ptr);

//All values have been verified by printing their outputs...
// printf("%hd %d %hd %d %x %d %d %d",bytesPerSec,secPerClus,reservedSecCount,numFats,mediaType,totSec,fatSize,rootClus);

firstDataSector=reservedSecCount+(numFats*fatSize)+rootDirSectors;
dataSec=totSec - (reservedSecCount + (numFats*fatSize)) + rootDirSectors;
countOfClus=dataSec/secPerClus;
if(countOfClus<LIMIT_FAT32)
exit(0);http://www.cplusplus.com/forum/windows/21731/#

}
Apr 2, 2010 at 9:16am
First, here's a modified open_drive function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


#pragma pack(1)
typedef struct __BIOS_PARAMETER_BLOCK_
{
/* BYTES    type         name               what holds
 0-2  */  	BYTE	jmp_code[3];           /* Jmp code to boot_code[0]
 3-10*/	    BYTE	oem_name[8];	       /* oem name

 11-12*/	WORD	sector_size;	       /* Logical sector size
 13   */	BYTE	sec_per_clus;	       /* Sectors per cluster
 14-15*/	WORD	reserved;	           /* Reserved sectors
 16  */	    BYTE	fat_count;		       /* Number of FATs
 17-18*/	WORD	max_root_dir;	       /* Max files in root dir (0 for fat32)
 19-20*/	WORD	total_sectors_small;   /* total small sectors    (for fat12 only?)
 21*/	    BYTE	media_type;		       /* Media type
 22-23*/	WORD	sectors_per_fat;	   /* Sectors per FAT
 24-25*/	WORD	sectors_per_track;	   /* Sectors per track
 26-27*/	WORD	total_heads;		   /* Number of heads
 28-30*/	DWORD	hidden_sectors;		   /* Hidden sectors
 31-33*/	DWORD	total_sectors_large;   /* Total large sectors
 34*/       BYTE    drive_no;              /*
 35*/       BYTE    dirty;                 /* is dirty, 1 tells chkdsk.exe to check disk
 36*/       BYTE    ebs;                   /* extended boot record signature
 37-41*/    DWORD   serial_number;         /* voulme serial number
 42-53*/    BYTE    label[11];             /* Volume label
 54-62*/    BYTE    fs_string[8];          /* FS string


 63-510*/   BYTE    boot_code[448];         /* bootable code -- not used in this program
 511-512*/  WORD    boot_signature;         /* Bootable volume sign  (AA55 )*/

}BOOT_SECTOR;
#pragma pack(0)

BOOT_SECTOR bs;





void open_drive(char * BUF)
{
//BUF value is \\\\.\\G:
void* ptr;
char* buffer = (char*)malloc (bytesPerSec);
DWORD bytesread;
HANDLE hDevice = CreateFile(BUF,GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, 0, NULL);

if (hDevice == INVALID_HANDLE_VALUE)
{
printf("This is not working :-(");
printf("\n\n%s\n",BUF);
getchar();
exit(0);
}

SetFilePointer (hDevice, 0, NULL, FILE_BEGIN);

if (!ReadFile (hDevice, &bs, bytesPerSec, &bytesread, NULL) )
exit(0);


bytesPerSec=bs.sector_size;
secPerClus=bs.sec_per_clus;
reservedSecCount=bs.reserved;
numFats=bs.fat_count;
mediaType=bs.media_type;
totSec=bs.total_sectors_large;
fatSize=bs.sectors_per_fat;

/*
rootClus= //????
*/
//All values have been verified by printing their outputs...
// printf("%hd %d %hd %d %x %d %d %d",bytesPerSec,secPerClus,reservedSecCount,numFats,mediaType,totSec,fatSize,rootClus);

firstDataSector=reservedSecCount+(numFats*fatSize)+rootDirSectors;
dataSec=totSec - (reservedSecCount + (numFats*fatSize)) + rootDirSectors;
countOfClus=dataSec/secPerClus;
if(countOfClus<LIMIT_FAT32)
exit(0);

lastClus(countOfClus);

}

Also, you can try to open disk without FILE_SHARE_WRITE attribute.
Second, what exactly lastClus function does? It seems that that you want to mark entries as EOF or what?

Apr 2, 2010 at 9:36am
lastClus function goes to the fat32 table and calculates the first cluster of the file. Then it goes to the next cluster and setting the value of the previous cluster no. to 0 which means this cluster is free. By doing this for all the clusters of a file, the file gets deleted.
Apr 2, 2010 at 6:23pm
Now I am able to delete the files but another problem is coming. When I delete the file, the space freed is not updated in the usb pendrive. where to update these entries. I tried to do check the FSINFO but its not working .



Apr 2, 2010 at 9:02pm
I guess WriteFile fails... Try to dismount and lock volume:
1
2
3
DeviceIoControl(hDisk,FSCTL_DISMOUNT_VOLUME,0,0,0,0,&dwReturned,0);

DeviceIoControl(hDisk,FSCTL_LOCK_VOLUME,0,0,0,0,&dwReturned,0);

note: FSCTL_DISMOUNT_VOLUME fails if there's at least one file opened in that volume.
Hope this helps.
Apr 4, 2010 at 11:18am
Where is the information related to free space in a usb drive gets stored?
I have deleted the file by changing the first character to oxe5 . But by doing these the space freed is not updated in the drive.
Please suggest some solution.
Apr 6, 2010 at 12:03am
If I'm an idiot please call me an idiot but I have to ask is the file that you are targeting fragmented? I only bring this up because you are attempting to write to specific addresses on the table and if they are not sequntial then maybe this won't work?

I'm facinated by this code by the way, I use these forums as a way to study and this is really helping me understand a few things.
Apr 6, 2010 at 4:51pm
Each fat table entry links to another fat entry and this doesn't have to be sequential. As far as I know file allocation table is just an array of 32 bit integers. Each element ( 32 bit integer) represent a cluster on disk. Every 32 bit integer points to another 32bit integer and so on until integer with value of 0xFFFFFFFF (end of file mark) is found. So each entry can point to any other entry and one part of file can be stored in the beginning of disk while other somewhere in the middle of disk

FAT overview:
http://staff.washington.edu/dittrich/misc/fatgen103.pdf
More:
http://www.pjrc.com/tech/8051/ide/fat32.html
fat io library
http://www.robs-projects.com/filelib.html
Topic archived. No new replies allowed.