How to Delete a file entry in fat32 directory stracture

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

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.
Thank you very much
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?
May be I am not able to write back to the disk. Is there any access problem?????
the WriteFile function in not writing on the disk

Is there any special permissions required for writing to the disk??
Can you post code that opens the disk? Also, what is your OS?
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/#

}
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?

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.
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 .



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.
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.
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.
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.