장 – 15
데이터 와이퍼를 위한 프로그래밍
소개
디스크에서 파일을 삭제할 때 정보가 드라이브에서 완전히 지워지지는 않지만 새 데이터를 덮어쓸 수 있는 것으로 표시된다는 점에 대해 이미 논의했습니다.
드라이브를 포맷하면 FAT 및 루트 디렉터리 항목과 같은 드라이브의 모든 파일 및 디렉터리 정보가 지워지지만 데이터 영역은 변경되지 않고 디스크의 데이터 영역에서 지워지지 않습니다. 운영 체제를 사용하여 삭제되거나 포맷된 데이터는 그대로 데이터 영역에 남아 있으며 일부 데이터 복구 노력 및 데이터 복구 소프트웨어로 복구할 수 있습니다.
따라서 드라이브에서 데이터를 완전히 제거해야 하므로 디스크에서 데이터를 완전히 지우는 프로그램이 필요합니다. 이렇게 하려면 파일을 삭제하거나 드라이브를 포맷하는 것만으로는 충분하지 않지만 디스크의 데이터를 다른 데이터로 덮어써야 합니다.
디스크에서 데이터를 완전히 지우는 데 사용되는 프로그램을 데이터 삭제 프로그램이라고 합니다. 이 프로그램은 데이터를 덮어쓰고 이전에 디스크에 저장된 모든 정보를 지우기 위해 데이터 영역에 임의의 문자를 기록합니다.
데이터를 완전히 복구할 수 없는 경우
데이터를 지우려면 디스크의 데이터 영역을 다른 데이터로 덮어써야 하지만 문제는 여기서 끝나지 않습니다. 상황을 더욱 복잡하게 하는 것은 덮어쓴 데이터를 기억하는 자기 드라이브의 경향이 있기 때문에 정교한 데이터 복구 도구로도 복구할 수 없도록 데이터를 임의의 데이터 시퀀스로 여러 번 덮어써야 한다는 것입니다.
간단한 데이터 와이퍼를 사용해도 데이터를 복구할 수 있는 기술이 현재 나와 있기 때문입니다.
일부 데이터 삭제 제품은 데이터에 대해 이진 0과 이진 1을 덮어씁니다. 일련의 이진 0과 이진 1을 쓰면 이 값이 각각 최소 및 최대 자기 값이므로 가장 깊은 덮어쓰기 효과를 얻을 수 있습니다.
이것이 이상적인 데이터 삭제 프로그램의 이론이지만 일반적으로 임의의 ASCII 문자로 데이터를 덮어쓰는 것으로 충분합니다. 그렇게 말하는 이유는 정교한 복구 도구 및 기술에 의한 복구는 일상적인 데이터 복구를 위해 조직의 데이터를 복구하는 데 사용할 수 없기 때문입니다. 이러한 기술은 단일 복구에도 매우 비싸고 수백만 달러의 비용이 들기 때문입니다. 이뿐만 아니라 이러한 기술은 전 세계적으로 소수의 국가에서만 사용할 수 있습니다.
디스크에서 데이터를 지우기 위한 단순 데이터 덮어쓰기에 대해서만 논의합니다. 그러나 약간의 노력으로 임의의 문자를 작성하도록 동일한 프로그램을 추가로 수정할 수 있습니다. 이 아이디어로 지워진 데이터는 데이터 복구 소프트웨어로도 복구할 수 없습니다.
데이터 삭제가 중요한 이유
데이터 복구 기술에 대해 논의할 때 일부 일반 또는 특정 데이터 복구 노력으로 데이터를 복구할 수 있음을 사용자에게 확신합니다. 그러나 데이터 복구가 모든 사람에게 항상 원하고 기대되는 기능은 아닙니다.
어떤 방법으로도 복구할 수 없도록 디스크의 데이터를 항상 지우려는 사람이나 조직이 많이 있을 수 있습니다. 이러한 경우에 매우 민감한 데이터가 이전에 디스크에 저장되었을 수 있으며, 잘못된 손에 들어가면 정보를 오용하여 조직이나 사용자에게 피해를 줄 수 있습니다.
하드 디스크에 더 많은 공간에 대한 요구 사항이 나날이 증가하고 있음을 알고 있습니다. 그 결과 거의 모든 조직에서 매년 대규모로 구형 소용량 드라이브를 새로운 대용량 디스크로 교체하고 있습니다. 이러한 오래된 디스크를 잘못된 사람이 가져갈 경우 해당 조직에 매우 심각한 문제가 발생할 수 있습니다.
CNET News.com이 2003년 1월 16일에 발행한 뉴스에 따르면 매사추세츠 공과대학(Massachusetts Institute of Technology)의 학생인 Simon Garfinkel과 Abbi Shelat은 연구의 이름으로 웹 및 기타 중고에서 오래된 하드 드라이브를 구입했습니다. 사람들이 지우려고 애쓰지 않는 엄청난 양의 개인 정보를 발견하기 위한 판매.
약 US$1000에 158개의 드라이브를 구입한 후 그들은 5000개가 넘는 신용 카드 번호, 의료 기록, 상세한 개인 및 기업 재무 정보, 몇 기가바이트의 전자 메일, 소스 코드 및 기타 정보를 수집했습니다.
이 두 학생은 "전달된 데이터의 기억: 디스크 위생에 대한 연구"라는 제목의 보고서를 작성했습니다. IEEE Security and Privacy 2월호에 게재되었습니다.
조사 결과 주요 요점은 하드 드라이브의 중고 시장이 개인 정보로 가득 차 있어 악의적인 구매자가 다른 사람의 신원을 매우 쉽게 추측할 수 있다는 것입니다.
비파괴 데이터 와이퍼
용 프로그램 작성
비파괴 데이터 와이퍼는 전체 "할당되지 않은 공간"을 지울 수 있는 일종의 데이터 삭제 프로그램입니다. 어떤 식 으로든 디스크에 저장된 데이터를 손상시키지 않고 디스크 볼륨의.
이러한 데이터 와이퍼의 범위는 디스크 볼륨의 할당되지 않은 공간을 모두 지우고 볼륨에 저장된 할당된 데이터는 그대로 유지해야 하는 경우입니다. 이러한 유형의 데이터 삭제 프로그램은 삭제된 파일의 데이터 영역도 삭제합니다.
비 – 파괴적인 데이터 삭제 프로그램이 다음에 주어졌습니다:
///// 비파괴 데이터 와이퍼 프로그램 \\\\\
#include <stdio.h>
unsigned int file_num=0; /* Provides File Number
During the Auto Creation
of Temporary Data files */
float status=0; /* How Much Disk space is
still Written */
static char dbuf[40000]; /* Data Buffer to write
Temporary Files with */
char file_extension[5]=".ptt";/* Unique Extensions for
Temporary Files */
char temp[5]; /* File Number converted to
String */
char filename[40]; /* Temporary File name */
void main()
{
unsigned int i=0;
clrscr();
while(i<40000)
{
dbuf[i] = ' ';
i++;
}
gotoxy(10,14);cprintf(" MB Still Written...");
while(1)
{
/* 고유한 이름으로 임시 파일을 자동으로 생성하는 로직 */
strcpy(filename,"TTPT");
itoa(file_num,temp,10);
strcat(filename,temp);
strcat(filename,file_extension);
file_num++;
write_to_temp(filename);
}
} //// End of Main \\\\
///// 임시 파일에 데이터를 쓰는 기능 \\\\\
write_to_temp(char *filename)
{
unsigned int i, count=1;
float buf_status=0;
FILE *tt;
if((tt=fopen(filename,"wb"))==NULL)
{
fclose(tt);
printf("\n Error occurred while creating temporary
file, ");
printf("\n Removing temporery Files After KEY BOARD
HIT");
getch();
remove_temp_file();/* Remove All temporary files */
}
while(1)
{
for(i=0;i<50;i++)
{
fprintf(tt,"%s",dbuf);
}
buf_status = (float)((40000*50*count)/512);
status= status+(40000*50);
count++;
gotoxy(10,14);
cprintf("%.0f",(float)(status/1000000));
if(kbhit())
{
fclose(tt);
printf("\n Removing Temporery Files, Please
Wait...");
remove_temp_file();
}
if(buf_status>=10000)
{
fclose(tt);
return;
}
}
}
/* 임시 파일을 자동으로 삭제하는 기능 */
remove_temp_file()
{
int i=0;
for(i=0;i<=file_num;i++)
{
strcpy(filename,"TTPT");
itoa(i,temp,10);
strcat(filename,temp);
strcat(filename,file_extension);
remove(filename);
}
exit(1);
return 0;
}
논리 및 프로그램 코딩에 대한 설명:
이 프로그램에서는 기본적으로 디스크의 할당되지 않은 공간을 지우기 위해 다음 두 단계를 따릅니다.
- 자동으로 임시 데이터 파일 만들기: 먼저 고유한 이름을 가진 임시 파일을 만들고 디스크 볼륨이 이러한 임시 데이터 파일로 가득 찰 때까지 일부 데이터를 포함합니다. 이렇게 하면 논리 드라이브의 할당되지 않은 모든 데이터 영역이 임시 파일의 데이터로 점유되고 할당되지 않은 모든 데이터를 덮어씁니다.
이를 위해 임시 파일 이름을 TTPTxxxx.PTT 형식으로 선택했습니다. 즉, 임시 파일의 처음 4자는 TTPT이고 파일 확장자는 .PTT입니다. 이는 임시 파일에 고유한 파일 이름을 제공하기 위해 수행됩니다.
단일 임시 파일의 최대 크기를 약 11,718섹터 데이터와 동일하게 설정했지만 사용자에 따라 정의할 수 있습니다. 나는 공백 문자 “ ” (ASCII 문자 32) 임시 파일의 데이터를 채웁니다. 그러나 공백 대신 임의의 문자를 사용할 수도 있습니다.
- 모든 임시 파일 제거: 논리 드라이브가 임시 파일로 가득 차면 할당되지 않은 모든 데이터 영역을 이제 덮어씁니다. 이제 프로그램에서 만든 모든 임시 파일이 자동으로 제거됩니다. 따라서 할당되지 않은 공간이 지워집니다.
프로그램 코딩에서 문자 배열 파일 이름은 파일 이름을 저장하여 다른 이름으로 임시 파일을 자동으로 생성합니다.
함수 write_to_temp(파일 이름); 40,000바이트의 데이터 버퍼 dbuf의 도움으로 임시 파일을 최대 11,718섹터(버퍼의 지정된 그룹 쓰기에서 10,000섹터의 발생이 없기 때문에) 등가 데이터를 채웁니다. 쓰기 속도를 높이기 위해 한 번에 50번의 데이터 버퍼를 작성합니다.
디스크 볼륨이 가득 차서 파일 생성 오류가 발생할 때까지 임시 파일이 생성됩니다. remove_temp_file() 함수는 프로그램에 의해 생성된 모든 임시 파일을 제거합니다.
이렇게 하면 디스크 볼륨의 데이터를 손상시키지 않고 할당되지 않은 모든 공간이 지워집니다.
Destructive Data Wiper용 프로그램 작성:
파괴적인 데이터 삭제 프로그램은 디스크 표면에 직접 기록하는 프로그램입니다. 이러한 유형의 데이터 삭제 프로그램은 파일 시스템 및 운영 체제보다 낮은 수준에서 작동하므로 OS, 파일 시스템, 디렉토리 항목 및 디스크에 기록된 모든 항목을 포함한 모든 데이터 및 기타 논리적 정보가 삭제됩니다.
이 데이터 삭제 프로그램은 디스크 표면의 섹터를 직접 지우고 디스크에 기록된 모든 것을 지웁니다. 운영 체제를 포함한 디스크의 모든 데이터가 손실되므로 이러한 프로그램을 파괴적인 데이터 삭제 프로그램이라고 합니다.
이러한 유형의 삭제 프로그램은 사용자가 운영 체제와 디스크의 모든 데이터를 포함하여 디스크의 모든 것을 덮어쓰려는 경우에 선호됩니다.
그러나 이러한 유형의 데이터 삭제 프로그램에는 몇 가지 더 많은 이점이 있습니다. 이러한 파괴적인 데이터 삭제 프로그램은 OS 및 파일 시스템에서 완전히 무료로 작동하고 디스크 표면에 직접 쓰기 때문에 비파괴적인 데이터 삭제 프로그램보다 합리적으로 빠릅니다.
또한, 임의의 데이터를 불법적으로 저장하여 디스크에 논리적 불량 섹터가 생성되는 경우 이러한 논리적 불량 섹터도 디스크의 데이터와 함께 완전히 지워집니다.
파괴적인 데이터 삭제 프로그램에 대한 코딩은 다음과 같습니다. 이 프로그램은 대용량 디스크도 지원하도록 작성되었습니다. 프로그램은 컴퓨터에 연결된 두 번째 물리적 하드 디스크의 데이터를 지웁니다.
///// 파괴적인 데이터 삭제 프로그램을 위한 코딩 \\\\\
#include<stdio.h>
#include<dos.h>
/* INT 13H 확장, 기능 번호 0x48을 사용하는 getdrivegeometry 기능에서 사용할 구조입니다. */
struct geometry
{
unsigned int size ; /* (call) size of Buffer */
unsigned int flags ; /* Information Flags */
unsigned long cyl ; /* Number of Physical Cylinders on
Drive */
unsigned long heads ;/* Number of Physical Heads on
Drive */
unsigned long spt ; /* Number of Physical Sectors Per
Track */
unsigned long sectors[2] ; /* Total Number of
Sectors on Drive */
unsigned int bps ; /* Bytes Per Sector */
} ;
/* 디스크 주소 패킷 형식의 구조 writeabsolutesectors 기능에서 사용 */
struct diskaddrpacket
{
char packetsize ; /* Size of Packet,
generally 10H */
char reserved ; /* Reserved (0) */
int blockcount ; /* Number of Blocks to
Transfer */
char far *bufferaddress ; /* address to Transfer
Buffer */
unsigned long blocknumber[2] ; /* Starting Absolute
Block Number */
} ;
///// 드라이브 매개변수를 가져오는 함수 \\\\\
unsigned long getdrivegeometry (int drive)
{
union REGS i, o ;
struct SREGS s ;
struct geometry g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
i.h.ah = 0x48 ; /* Function Number 0x48 of INT 13H
Extensions */
i.h.dl = drive; /* Drive Number */
i.x.si = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* 세그먼트 레지스터 값을 사용하여 INT 13H 확장의 지정된 기능 번호를 호출합니다. */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Head = %lu, Sectors Per Track = %lu, Cylinder =
%lu\n",
g.heads,g.spt,g.cyl);
/* 드라이브 기하학 기능 가져오기가 실패하면 오류 메시지를 표시하고 종료 */
if(g.spt==0)
{
printf("\n Get Drive Geometry Function Fails....");
printf("\n Extensions Not Supported, Press any Key to
Exit...");
getch();
exit(1);
}
return *g.sectors; /* Return The Number of
Sectors on Drive */
}
void main()
{
unsigned long loop=0, Sectors_in_ HDD2=0;
unsigned char buffer[61440]; /* Data buffer of 61440
bytes Equivalent to
120 Sectors */
unsigned long i=0;
char choice;
clrscr();
/* 총수인 경우 연결된 하드 디스크의 수는 오류 메시지 표시 및 종료 2개 미만입니다. */
if(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n You Must Have At least Two Hard Disks
Attached to your Computer To Run This");
printf("\n Program. This Program has been developed
to Wipe the Data of Second Hard Disk.");
printf("\n Press any Key to Exit... ");
getch();
exit(1);
}
Sectors_in_HDD2 = getdrivegeometry (0x81);
printf(" Total Sectors in Second Hard Disk =
%lu\n\n",
Sectors_in_HDD2);
///// 먼저 확인 후 진행 \\\\\
printf("\n It is A Data Wiping Program, and Writes on
the Surface of the Disk,");
printf("\n After running this program, Data can not
be recovered by any Software,");
printf("\n All The Data in Second Hard Disk will be
lost !!!");
printf("\n Press \'Y\' to Continue, Else any key to
Exit... ");
choice = getche();
switch(choice)
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
gotoxy(10,15);cprintf(" Initializing, Please Wait...");
for(i=0;i<61440;i++)
{
buffer[i]='\0';
}
gotoxy(10,15);cprintf(" ");
gotoxy(10,15);
printf("Currently Wiping Absolute Sector: ");
for(loop=0;loop<= Sectors_in_HDD2;loop=loop+120)
{
writeabsolutesectors (0x81, loop, 120, buffer);
gotoxy(44,15); printf("%ld",loop);
if(kbhit())
{
exit(0);
}
///// 완료 시 메시지 표시 \\\\\
printf("\n\n Data wiping is Now Completed, All the Data in
Second Hard Disk is now");
printf("\n Completely Erased, Press any Key to Exit...");
getch();
}
//// 절대 섹터 쓰기 기능 \\\\
int writeabsolutesectors ( int drive, unsigned long sectornumber, int numofsectors, void *buffer )
{
union REGS i, o ;
struct SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* Packet Size = 10H */
pp.reserved = 0 ; /* Reserved = 0 */
pp.blockcount = numofsectors ;/* Number of Sectors to
be written */
/* 데이터 버퍼용 */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Sector number
to be written*/
pp.blocknumber[1] = 0 ; /* Block number = 0 */
i.h.ah = 0x43 ; /* Function Number */
i.h.al = 0x00 ; /* Write Flags */
i.h.dl = drive ; /* Physical Drive
number */
i.x.si = FP_OFF ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
/* 세그먼트 레지스터 값으로 INT 13H의 지정된 기능을 호출합니다 */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; //failure
else
return 1 ; // success
}
코딩에 대한 의견:
구조 지오메트리는 디스크의 다양한 매개변수를 가져오기 위해 INT 13H 확장, 기능 번호 0x48을 사용하는 getdrivegeometry 기능에서 사용됩니다.
diskaddrpacket 구조는 writeabsolutesectors 기능에서 사용할 디스크 주소 패킷 형식입니다.
기능 getdrivegeometry(int drive)는 디스크 지정된 물리적 드라이브 번호 드라이브의 드라이브 매개변수를 가져오는 것입니다. 버퍼[61440]는 61440바이트의 데이터 버퍼로, 120섹터에 해당합니다.
(char) peekb(0x0040, 0x0075)는 세그먼트 0040H:offset 0075H로 표시되는 메모리 위치에 저장된 컴퓨터에 연결된 하드 디스크의 수를 찾는 데 사용됩니다. 연결된 총 하드 디스크 수가 2개 미만이면 오류 메시지를 표시하고 종료합니다.
writeabsolutesectors ( 0x81, loop, 120, buffer ) 함수는 루프에서 지정한 절대 섹터 번호부터 한 번에 120개 섹터에 데이터 버퍼의 데이터를 쓰는 데 사용됩니다.
나는 ‘\0’ (NULL 문자, ASCII 코드 0) 데이터를 덮어쓸 섹터에 기록합니다. 그러나 임의의 문자를 사용하여 데이터를 덮어쓸 수 있습니다.
함수 writeabsolutesectors 및 getdrivegeometry에 대한 자세한 설명은 이 책의 앞부분에 제공된 장을 참조하십시오.
특정 파일의 데이터 영역 지우기
디스크의 할당되지 않은 공간의 데이터를 지우거나 전체 디스크를 지우는 데이터 지우기 프로그램에 대해 논의했습니다. 그러나 사용자가 데이터를 삭제할 때마다 데이터를 지우려는 경우 디스크의 할당되지 않은 전체 공간을 지우는 데 시간이 걸릴 수 있습니다.
특정 파일이 차지하는 데이터 영역만 지우려면 이러한 유형의 데이터 지우기 프로그램이 필요합니다. 이를 위해 FAT 및 루트 디렉토리 항목의 도움을 받아 특정 파일이 차지하는 데이터 영역을 찾습니다.
플로피의 경우에도 데이터가 조각화되지 않으면 루트 디렉터리 정보의 도움으로만 조각화할 수 있습니다. 다음 표는 모든 파일에 대해 루트 디렉토리 항목이 32바이트로 저장한 정보를 보여줍니다.
루트 디렉토리 항목의 목차에서 볼 수 있듯이 파일의 시작 및 끝 클러스터를 찾을 수 있습니다. 파일 이름의 첫 번째 바이트에는 파일에 대한 몇 가지 중요한 정보가 포함될 수도 있습니다. 이 바이트가 제공하는 정보는 다음 중 하나일 수 있습니다.
이 정보를 사용하여 1.44Mb, 3 ½ 루트 디렉토리 정보의 도움으로 인치 플로피 디스크. 플로피 디스크의 데이터가 단편화되지 않았다고 가정하면 다음에 주어진 프로그램은 데이터 영역에서 지정된 파일의 데이터를 지웁니다.
/* 플로피 디스크에서 지정된 파일의 데이터 영역을 지우는 프로그램 */
#include<stdio.h>
#include<dos.h>
///// 루트 디렉토리에서 32바이트의 파일 엔트리를 읽는 구조 \\\\\
struct root
{
unsigned char filename[8]; /* File name Entry of
8 Bytes */
unsigned char extension[3]; /* Extension of File of
3 Bytes */
unsigned char attribute; /* File Attribute Byte */
unsigned char reserved[10]; /* Reserved Bytes 10 */
unsigned int time; /* Time, 2 Bytes */
unsigned int date; /* Date, 2 Bytes */
unsigned int starting_cluster;/* Starting Cluster of File,
2 Bytes */
unsigned long file_size; /* File Size in Bytes,
4 Bytes */
};
/* 모든 루트 디렉토리 항목을 읽으려면 이것을 취해야 합니다. */
//struct root entry[224];
/* 루트 디렉토리의 한 섹터에 있는 16개의 파일 항목을 모두 읽는 구조 */
struct one_root_sector
{
struct root entry[16];
};
struct one_root_sector one;
void main()
{
int result, i, num_sectors,j;
char wipe_buf[512]; /* Data Buffer to be used to wipe
out the data Area of file */
clrscr();
result= absread(0x00, 1, 19, &one); /* Read Absolute Sector
19 (First Sector of Root Directory) */
if (result != 0)
{
perror("Error in Reading Sector, Press any key to
Exit...");
getch();
exit(1);
}
/* 루트 디렉토리에서 읽은 후 파일 정보 표시 */
printf(" FILE NO. FILENAME EXTENSION STARTING CLUSTER
FILESIZE \n\n");
for(i=1;i<16;i++)
{
printf("\n %5d %8.8s %3.3s %5u %10lu ",
i, one.entry[i].filename, one.entry[i].extension,
one.entry[i].starting_cluster, one.entry[i].file_size);
}
//// 파일 삭제를 위한 사용자 입력 받기 \\\\
printf("\n\n Enter The File Number, you Want to Delete and
Wipe out Completely ");
scanf("%d", &i);
if(i<1 || i>15)
{
printf(" \"%d\" is an Invalid Choice..., Press any
Key to Exit...", i);
getch();
exit(1);
}
///// 먼저 확인 후 계속 \\\\\\
printf("\n You are About to wipe-out,
The File \"%.8s.%s\"",
one.entry[i].filename,
one.entry[i].extension);
printf("\n Do you Want to Continue...(Y/N) ");
switch(getche())
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
///// 섹터의 파일 크기 계산 \\\\\
num_sectors = one.entry[i].file_size/512;
if((one.entry[i].file_size%512)>0)
{
num_sectors = num_sectors+1;
}
/* 512개의 NULL 문자가 있는 512바이트의 데이터 버퍼 */
for(j=0;j<512;j++)
{
wipe_buf[j] = '\0';
}
///// 파일의 시작 섹터 \\\\\
j= one.entry[i].starting_cluster+31;
/* 파일의 섹터가 끝날 때까지 데이터 영역 지우기 */
while(j!=(one.entry[i].starting_cluster +
num_sectors+31) )
{
if((abswrite(0x00, 1, j, &wipe_buf))!=0)
{
printf("\n Error Writing on Disk Sectors");
getch();
exit(0);
}
j++;
}
printf("\n\n File \"%.8s.%.3s\" Deleted !!!" ,
one.entry[i].filename,
one.entry[i].extension);
one.entry[i].attribute = 0; /* Set the File Attribute
to 0 */
one.entry[i].time = 0; /* Wipe The Time information
of File */
one.entry[i].date = 0; /* Wipe The Date information
of File */
one.entry[i].starting_cluster = 0; /* Set the Starting cluster to 0
*/
one.entry[i].file_size = 0; /* Set the file Size to 0 */
one.entry[i].filename[0]=0xE5; /* Give the Deleted
file Status to the File */
///// 루트 디렉토리에 위의 정보를 작성하십시오. \\\\\\
result= abswrite(0x00, 1, 19, &one);
if (result != 0)
{
perror("Error in Reading Sector, Press any key to
Exit...");
getch();
exit(1);
}
}
프로그램의 논리 및 코딩에 대한 설명:
구조 루트는 루트 디렉토리의 32바이트 파일 항목을 읽는 데 사용되며 구조 one_root_sector는 루트 디렉토리의 한 섹터에 있는 16개의 파일 항목 모두를 읽습니다.
루트 디렉토리 정보의 모든 섹터를 읽으려면 struct 루트 항목[224]으로 가져와야 합니다. 그러나 루트 디렉토리의 한 섹터만 16개 항목을 분석하는 프로그램을 작성했습니다.
파일의 시작 섹터는 다음과 같이 계산되었습니다.
j= one.entry[i].starting_cluster+31;
1.44MB, 3 ½ 인치 플로피 디스크는 플로피 디스크의 처음 32개 섹터 다음에 시작됩니다. 그리고 지정된 용량의 플로피 디스크에서 하나의 클러스터는 하나의 섹터에 속합니다.
다음 표는 1.44MB, 3½ 인치 플로피 디스크:
프로그램의 출력은 다음과 같이 표시됩니다.
여기에서 PARTBOOT.C 파일의 데이터를 삭제하고 지웠습니다. DIR 명령으로 플로피의 내용을 보면 PARTBOOT.C 파일이 표시되지 않습니다. 프로그램을 더 실행하면 삭제된 파일의 항목이 다음과 같이 표시됩니다.
여기서 문자 “” (0xE5), 파일이 삭제되었음을 나타냅니다. (파일 이름의 첫 번째 문자에 대한 표 참조).
하드 디스크 드라이브에 대해 동일한 프로그램을 작성하려면 루트 디렉토리가 있는 FAT도 사용하여 모든 파일의 데이터 영역 정보를 가져와야 합니다.
하드 디스크 드라이브의 조각난 데이터 비율은 오래된 파일이 삭제되고 새 파일이 생성됨에 따라 시간이 지남에 따라 증가하기 때문입니다. 그러면 드라이브에 있는 파일의 모든 데이터 클러스터가 데이터 영역에 계속해서 하나씩 있을 필요가 없습니다. FAT에 액세스하면 해당 클러스터에 모두 액세스할 수 있습니다.