장 - 15
데이터 정리를 위한 프로그래밍
소개
디스크에서 파일을 삭제할 때 해당 정보는 디스크에서 완전히 지워지지 않고, 새로운 데이터를 쓸 수 있도록 표시된다는 점은 이미 설명했습니다.
디스크를 포맷하면 FAT 및 루트 디렉토리 레코드와 같은 디스크의 파일 및 디렉토리에 대한 모든 정보가 지워지지만, 데이터 영역은 변경되지 않고 디스크의 데이터 영역의 아무것도 지워지지 않습니다. 운영 체제에 의해 삭제되거나 포맷된 데이터는 그대로 데이터 영역에 남아 있으며, 일부 데이터 복구 작업과 데이터 복구 소프트웨어를 통해 복구할 수 있습니다.
따라서 디스크에서 데이터를 완전히 삭제해야 할 경우 디스크에서 데이터를 완전히 지우는 프로그램이 필요합니다. 이를 위해서는 단순히 파일을 삭제하거나 디스크를 포맷하는 것만으로는 충분하지 않습니다. 디스크에 있는 데이터를 다른 데이터로 덮어써야 합니다.
디스크에서 데이터를 완전히 지우는 데 사용되는 프로그램을 데이터 지우기 프로그램이라고 합니다. 이러한 프로그램은 데이터 영역에 임의의 문자를 써서 데이터를 덮어쓰고 이전에 디스크에 저장된 모든 정보를 지웁니다.
데이터가 완전히 복구 불가능해질 때
데이터를 지우려면 디스크의 데이터 영역을 다른 데이터로 덮어써야 하지만 문제는 거기서 끝나지 않습니다. 문제를 더 복잡하게 만드는 것은, 자기 디스크가 덮어쓴 데이터를 기억하려는 경향으로 인해 데이터가 무작위 데이터 시퀀스로 여러 번 덮어쓰여져야 하므로, 정교한 데이터 복구 도구를 사용하더라도 복구할 수 없다는 것입니다.
오늘날에는 간단한 데이터 삭제 도구를 사용한 후에도 데이터를 복구할 수 있는 기술이 있기 때문입니다.
일부 데이터 삭제 제품은 데이터를 이진수 0과 2진수 1로 덮어씁니다. 이진수 0과 1의 시리즈를 쓰는 것은 가장 깊은 다시 쓰기 효과를 제공하는데, 이는 이러한 값이 각각 최소와 최대 자기 값이기 때문입니다.
이는 이상적인 데이터 삭제 프로그램에 대한 이론이지만 일반적으로는 임의의 ASCII 문자로 데이터를 덮어쓰는 것으로 충분합니다. 이렇게 말하는 이유는 정교한 복구 도구와 기술을 이용한 복구는 일상적인 데이터 복구를 위해 어떤 조직의 데이터도 복구하는 데 사용할 수 없기 때문입니다. 이러한 기술은 매우 비용이 많이 들고 단 한 번의 복구에도 수백만 달러가 듭니다. 그뿐만 아니라 이러한 기술은 전 세계 일부 국가에서만 이용할 수 있습니다.
디스크에서 데이터를 지우는 간단한 데이터 덮어쓰기에 대해서만 논의하겠습니다. 하지만 약간의 노력만으로 동일한 프로그램을 수정하여 무작위 문자만 쓸 수 있습니다. 이 아이디어로 지워진 데이터는 어떠한 데이터 복구 소프트웨어로도 복구할 수 없습니다.
데이터 삭제가 왜 중요한가요?
데이터 복구 방법을 논의할 때 우리는 일반적인 데이터 복구 작업이나 특별한 데이터 복구 작업을 통해 데이터를 복구할 수 있다는 점을 사용자에게 보장합니다. 하지만 데이터 복구는 모든 사람이 원하고 기대하는 기능은 아닙니다.
디스크에 있는 데이터를 복구할 수 없는 방식으로 항상 지우려는 사람이나 조직이 많을 것입니다. 이러한 경우 디스크에는 이전에 매우 민감한 데이터가 담겨 있었을 수 있으며, 이 데이터가 잘못된 사람의 손에 들어가면 정보의 부적절한 사용으로 인해 조직이나 사용자에게 피해를 입힐 수 있습니다.
아시다시피, 하드 드라이브 공간에 대한 필요성은 날이 갈수록 커지고 있습니다. 결과적으로 거의 모든 조직에서 오래되고 용량이 적은 드라이브가 매년 대규모로 새롭고 용량이 큰 드라이브로 교체되고 있습니다. 만약 이 오래된 디스크가 잘못된 사람의 손에 들어간다면, 해당 조직에 매우 심각한 문제가 발생할 수 있습니다.
2003년 1월 16일 CNET News.com에 게재된 뉴스 기사에 따르면 MIT 학생인 사이먼 가핑켈과 애비 셸랫은 연구 목적으로 인터넷과 기타 중고 드라이브 판매처에서 오래된 하드 드라이브를 구매해 사람들이 삭제하지 않는 엄청난 양의 개인 정보에 접근했습니다.
그들은 약 1,000달러에 드라이브 158개를 구입한 후 5,000개 이상의 신용카드 번호, 의료 기록, 자세한 개인 및 회사 재무 정보, 그리고 수 기가바이트에 달하는 이메일, 소스 코드 및 기타 정보를 수집했습니다.
이 두 학생은 연구 결과를 "전달된 데이터의 기억: 디스크 정리에 대한 연구"라는 제목의 보고서로 정리하여 IEEE 보안 및 개인 정보 보호 저널 2월호에 게재했습니다.
연구 결과에서 드러난 주요 사실은 하드 드라이브 중고 시장에는 개인정보가 가득 차 있어 악의적인 구매자가 다른 사람의 신원을 도용하기가 매우 쉽다는 것입니다.
비파괴적 데이터 와이퍼를 위한 프로그램 작성
비파괴적 데이터 삭제 프로그램은 디스크에 저장된 데이터를 어떤 식으로든 손상시키지 않고 디스크 볼륨의 "할당되지 않은 공간" 전체를 삭제할 수 있는 일종의 데이터 삭제 프로그램입니다.
이러한 데이터 와이퍼의 범위는 볼륨에 저장된 할당된 데이터가 손상되지 않은 상태에서 디스크 볼륨의 모든 할당되지 않은 공간을 지우려는 경우입니다. 이러한 유형의 데이터 삭제 프로그램은 삭제된 파일의 데이터 영역도 지웁니다.
비파괴적 데이터 삭제 프로그램의 유형에 대한 프로그램 코딩은 다음과 같습니다.
///// 비파괴 데이터 와이퍼 프로그램 \\\\\
#include <stdio.h>
unsigned int file_num=0; /* 파일 번호 제공
자동 생성 중
임시 데이터 파일 */
float status=0; /* 디스크 공간은 얼마인가
아직 쓰여있음 */
static char dbuf[40000]; /* 쓸 데이터 버퍼
*/를 포함한 임시 파일
char file_extension[5]=".ptt";/* 고유 확장자
임시 파일 */
char temp[5]; /* 파일 번호가 변환됨
끈 */
char filename[40]; /* 임시 파일 이름 */
void 메인()
{
부호 없는 int i=0;
영어: clrscr();
while(i<40000)
{
dbuf[i] = ' ';
나++;
}
gotoxy(10,14);cprintf("MB가 아직 쓰여짐...");
동안(1)
{
/* 고유한 이름으로 임시 파일을 자동으로 생성하는 논리 */
strcpy(파일명, "TTPT");
itoa(파일 번호, 임시, 10);
strcat(파일이름,임시);
strcat(파일이름,파일 확장자);
파일 번호++;
write_to_temp(파일 이름);
}
} //// 메인 끝 \\\\
///// 임시파일에 데이터를 쓰는 함수 \\\\\
write_to_temp(char *파일 이름)
{
부호 없는 int i, 개수=1;
float buf_status=0;
파일 *tt;
if((tt=fopen(파일명,"wb"))==NULL)
{
fclose(tt);
printf("\n 임시를 생성하는 동안 오류가 발생했습니다.
파일, ");
printf("\n KEY BOARD 후 임시 파일 제거
때리다");
getch();
remove_temp_file();/* 모든 임시 파일 제거 */
}
동안(1)
{
i=0;i<50;i++에 대하여
{
fprintf(tt, "%s",dbuf);
}
buf_status = (float)((40000*50*개수)/512);
상태=상태+(40000*50);
카운트++;
고톡시(10,14);
cprintf("%.0f",(float)(상태/1000000));
if(kbhit())
{
fclose(tt);
printf("\n 임시 파일을 제거해주세요
기다리다...");
임시파일 제거();
}
if(buf_status>=10000)
{
fclose(tt);
반품;
}
}
}
/* 임시 파일을 자동으로 삭제하는 기능 */
임시파일 제거()
{
int i=0;
i=0;i<=파일_번호;i++)
{
strcpy(파일명, "TTPT");
이것(i,temp,10);
strcat(파일이름,임시);
strcat(파일이름,파일 확장자);
파일이름을 제거합니다.
}
출구(1);
0을 반환합니다.
}
논리와 프로그램 코딩에 대한 의견:
이 프로그램에서는 기본적으로 다음 두 단계를 따라 디스크의 할당되지 않은 공간을 지웁니다.
- 임시 데이터 파일을 자동으로 만듭니다. 먼저 고유한 이름을 가진 임시 파일을 만들고 디스크 볼륨이 이러한 임시 데이터 파일로 가득 찰 때까지 일부 데이터를 포함합니다. 이렇게 하면 논리 드라이브의 모든 할당되지 않은 데이터 영역이 임시 파일의 데이터로 채워지고 모든 할당되지 않은 데이터가 덮어쓰기됩니다.
이를 위해, 나는 TTPTxxxx.PTT 형식으로 임시 파일의 이름을 선택했습니다. 즉, 임시 파일의 처음 네 글자는 TTPT이고 파일 확장자는 .PTT입니다. 이는 임시 파일에 고유한 파일 이름을 제공하기 위해 수행됩니다.
저는 단일 임시 파일의 최대 크기를 설정했는데, 이는 약 11,718개의 섹터 데이터와 동일하지만, 여러분이 원하는 대로 정의할 수 있습니다. 저는 임시 파일에 데이터를 채우기 위해 공백 문자 " "(ASCII 문자 32)를 선택했습니다. 그러나 공백 대신 임의의 문자를 사용할 수도 있습니다.
- 모든 임시 파일 제거: 논리 드라이브가 임시 파일로 가득 차면 할당되지 않은 모든 데이터 영역이 이제 덮어씌워졌다는 것을 나타냅니다. 이제 프로그램에서 만든 모든 임시 파일이 자동으로 제거됩니다. 따라서 할당되지 않은 공간이 지워집니다.
프로그램을 코딩할 때 문자 배열 파일 이름은 파일 이름을 저장하여 다른 이름의 임시 파일을 자동으로 생성합니다.
write_to_temp(filename); 함수는 버퍼의 지정된 그룹 쓰기에서 10,000개 섹터가 발생하지 않기 때문에 40,000바이트의 데이터 버퍼 dbuf의 도움으로 임시 파일을 최대 11,718개 섹터로 채웁니다. 쓰기 속도를 높이기 위해 한 번에 50개의 데이터 버퍼가 쓰여집니다.
임시 파일은 디스크 볼륨이 가득 차고 파일 생성 오류가 발생할 때까지 생성됩니다. remove_temp_file() 함수는 프로그램에서 생성한 모든 임시 파일을 제거합니다.
이런 식으로 디스크 볼륨의 데이터를 손상시키지 않고 할당되지 않은 모든 공간이 지워집니다.
파괴적 데이터 와이퍼를 위한 프로그램 작성:
파괴적인 데이터 삭제 프로그램은 디스크 표면에 직접 쓰는 프로그램입니다. 이러한 유형의 데이터 삭제 프로그램은 파일 시스템 및 운영 체제보다 낮은 수준에서 작동하므로 OS, 파일 시스템, 디렉토리 항목 및 디스크에 기록된 모든 것을 포함한 모든 데이터 및 기타 논리적 정보가 삭제됩니다.
이러한 데이터 삭제 프로그램은 디스크 표면의 섹터를 직접 삭제하고, 디스크에 기록된 모든 것을 삭제합니다. 운영 체제를 포함한 디스크의 모든 데이터가 손실되므로 이러한 프로그램을 파괴적 데이터 삭제 프로그램이라고 합니다.
이러한 유형의 삭제 프로그램은 사용자가 운영 체제와 디스크의 모든 데이터를 비롯하여 디스크에 있는 모든 것을 덮어쓰려는 경우에 선호됩니다.
하지만 이러한 유형의 데이터 삭제 프로그램에는 몇 가지 이점이 더 있습니다. 이러한 파괴적인 데이터 삭제 프로그램은 OS 및 파일 시스템에서 완전히 무료로 작동하고 디스크 표면에 직접 쓰기 때문에 비파괴적 데이터 삭제 프로그램보다 상당히 빠릅니다.
또한, 무작위 데이터를 불법적으로 저장하여 디스크에 논리적인 불량 섹터가 생성되는 경우, 이러한 논리적인 불량 섹터도 디스크의 데이터와 함께 완전히 지워집니다.
파괴적인 데이터 삭제 프로그램의 코딩은 다음과 같습니다. 이 프로그램은 대용량 디스크도 지원하도록 작성되었습니다. 이 프로그램은 컴퓨터에 연결된 두 번째 물리적 하드 디스크의 데이터를 삭제합니다.
///// 파괴적인 데이터 삭제 프로그램을 위한 코딩 \\\\\
#include<stdio.h>
#include<dos.h>
/* INT 13H 확장, 함수 번호 0x48을 사용하는 getdrivegeometry 함수에서 사용할 구조. */
구조 기하학
{
unsigned int size ; /* (호출) 버퍼 크기 */
unsigned int flags ; /* 정보 플래그 */
unsigned long cyl ; /* 물리적 실린더 수
운전하다 */
unsigned long heads ;/* 물리적 헤드의 수
운전하다 */
unsigned long spt ; /* 물리 섹터 수
길 */
unsigned long sectors[2] ; /* 총 섹터 수
드라이브의 섹터 */
unsigned int bps ; /* 섹터당 바이트 */
} ;
/* writeabsolutesectors 함수에서 사용되는 디스크 주소 패킷 형식의 구조 */
구조체 디스크 주소 패킷
{
char packetsize ; /* 패킷 크기,
일반적으로 10H */
char reserved ; /* 예약됨 (0) */
int blockcount ; /* 블록 수
옮기다 */
char far *bufferaddress ; /* 전송할 주소
버퍼 */
unsigned long blocknumber[2] ; /* 절대 시작
블록 번호 */
} ;
///// 드라이브 매개변수를 가져오는 함수 \\\\\
unsigned long getdrivegeometry(int drive)
{
유니온 REGS i, o;
구조체 SREGS s;
구조체 기하 구조 g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
ihah = 0x48 ; /* INT 13H의 함수 번호 0x48
확장 */
ihdl = 드라이브; /* 드라이브 번호 */
ixsi = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* 세그먼트 레지스터 값을 사용하여 INT 13H 확장의 지정된 함수 번호를 호출합니다. */
int86x(0x13, &i, &o, &s);
printf("\n Head = %lu, 트랙당 섹터 = %lu, 실린더 =
%lu\n",
g.헤드, g.spt, g.실린더);
/* 드라이브 지오메트리 함수가 실패하면 오류 메시지를 표시하고 종료합니다. */
if(g.spt==0)
{
printf("\n 드라이브 지오메트리 가져오기 함수가 실패했습니다....");
printf("\n 확장이 지원되지 않습니다. 아무 키나 누르세요.
출구...");
getch();
출구(1);
}
return *g.sectors; /* 섹터 수를 반환합니다.
드라이브의 섹터 */
}
void 메인()
{
부호 없는 긴 루프=0, Sectors_in_ HDD2=0;
unsigned char buffer[61440]; /* 61440의 데이터 버퍼
바이트와 동일함
120개 섹터 */
부호 없는 long i=0;
캐릭터 선택;
영어: clrscr();
/* 연결된 하드 디스크의 총 수가 2개 미만이면 오류 메시지를 표시하고 종료합니다. */
if(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n 최소한 두 개의 하드 디스크가 있어야 합니다.
이것을 실행하려면 컴퓨터에 연결하세요");
printf("\n 프로그램. 이 프로그램은 개발되었습니다.
두 번째 하드 디스크의 데이터를 삭제합니다.");
printf("\n 종료하려면 아무 키나 누르세요...");
getch();
출구(1);
}
Sectors_in_HDD2 = getdrivegeometry(0x81);
printf("두 번째 하드 디스크의 총 섹터 =
%루\n\n",
HDD2의 섹터)
///// 먼저 확인 후 진행하세요 \\\\\
printf("\n 데이터를 삭제하는 프로그램이며 다음과 같이 씁니다.
디스크의 표면,");
printf("\n 이 프로그램을 실행한 후, Data를 얻을 수 없습니다.
어떠한 소프트웨어로도 복구할 수 없음");
printf("\n 두 번째 하드 디스크의 모든 데이터는
잃어버린 !!!");
printf("\n 계속하려면 \'Y\'를 누르세요. 그렇지 않으면 아무 키나 누르세요.
출구... ");
선택 = getche();
스위치(선택)
{
케이스 'y':
케이스 'Y':
부서지다;
기본:
종료(0);
}
gotoxy(10,15);cprintf("초기화 중, 잠시만 기다려 주세요...");
i=0;i<61440;i++에 대하여
{
버퍼[i]='\0';
}
고톡시(10,15);cprintf(" ");
고톡시(10,15);
printf("현재 절대 섹터를 삭제 중입니다: ");
for(loop=0;loop<= Sectors_in_HDD2;loop=loop+120)
{
writeabsolutesectors(0x81, 루프, 120, 버퍼);
gotoxy(44,15); printf("%ld",loop);
if(kbhit())
{
종료(0);
}
///// 완료되면 메시지 표시 \\\\\
printf("\n\n 데이터 삭제가 완료되었습니다. 모든 데이터는
두 번째 하드 디스크는 이제 ");
printf("\n 완전히 지워졌습니다. 종료하려면 아무 키나 누르세요...");
getch();
}
//// 절대 섹터를 쓰는 함수 \\\\
int writeabsolutesectors(int 드라이브, unsigned long 섹터 번호, int numofsectors, void *버퍼)
{
유니온 REGS i, o;
구조체 SREGS s;
구조체 diskaddrpacket pp;
pp.packetsize = 16 ; /* 패킷 크기 = 10H */
pp.reserved = 0 ; /* 예약됨 = 0 */
pp.blockcount = numofsectors ;/* 블록을 생성할 섹터 수
쓰여지다 */
/* 데이터 버퍼용 */
pp.버퍼 주소 = (char far*) MK_FP ( FP_SEG((void far*)버퍼), FP_OFF((void far*)버퍼));
pp.blocknumber[0] = sectornumber ; /* 섹터 번호
쓰여질 것이다*/
pp.blocknumber[1] = 0 ; /* 블록 번호 = 0 */
ihah = 0x43 ; /* 함수 번호 */
ihal = 0x00 ; /* 플래그 쓰기 */
ihdl = 드라이브; /* 물리적 드라이브
숫자 */
ixsi = FP_OFF ( (void far*)&pp ) ; /* ds:si에 대한
버퍼 매개변수 */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:say에 대한
버퍼 매개변수 */
/* 세그먼트 레지스터 값을 사용하여 INT 13H의 지정된 함수를 호출합니다. */
int86x(0x13, &i, &o, &s);
if ( oxcflag==1)
return 0 ; // 실패
또 다른
return 1 ; // 성공
}
코딩에 대한 의견:
구조 기하학은 INT 13H 확장, 함수 번호 0x48을 사용하는 getdrivegeometry 함수에서 디스크의 다양한 매개변수를 가져오는 데 사용됩니다.
구조 diskaddrpacket은 writeabsolutesectors 함수에서 사용되는 디스크 주소 패킷 형식을 위한 것입니다.
함수 getdrivegeometry(int drive)는 지정된 물리적 드라이브 번호 drive의 드라이브 매개변수를 가져옵니다. 버퍼[61440]는 61440바이트의 데이터 버퍼로 120개 섹터와 동일합니다.
(char) peekb(0x0040, 0x0075)는 세그먼트 0040H:오프셋 0075H로 표현되는 메모리 위치에 저장된 컴퓨터에 연결된 하드 디스크의 수를 찾는 데 사용됩니다. 연결된 하드 디스크의 총 수가 2개보다 적으면 오류 메시지를 표시하고 종료합니다.
writeabsolutesectors(0x81, loop, 120, buffer) 함수는 loop에서 지정한 절대 섹터 번호부터 시작하여 한 번에 120개 섹터에 데이터 버퍼의 데이터를 쓰는 데 사용됩니다.
나는 데이터를 덮어쓰기 위해 섹터에 쓰기 위해 '\0' (NULL 문자, ASCII 코드 0)을 선택했습니다. 그러나 무작위 문자를 사용하여 데이터를 덮어쓸 수 있습니다.
writeabsolutesectors 및 getdrivegeometry 함수에 대한 자세한 설명은 이 책의 앞부분에 나와 있는 장을 참조하세요.
특정 파일의 데이터 영역 삭제
우리는 디스크의 할당되지 않은 공간의 데이터를 지우거나 전체 디스크를 지우는 데이터 지우기 프로그램에 대해 논의했습니다. 하지만 사용자가 데이터를 삭제할 때마다 데이터를 지우려고 한다면, 디스크의 할당되지 않은 전체 공간을 지우는 데 시간이 걸리는 프로세스가 될 수 있습니다.
우리는 특정 파일이 차지하는 데이터 영역만 지우기 위해 이런 유형의 데이터 지우기 프로그램이 필요합니다. 이를 위해 우리는 FAT 및 루트 디렉토리 항목에서 도움을 받아 특정 파일이 차지하는 데이터 영역을 찾습니다.
플로피의 경우에도 데이터가 조각나지 않았다면 루트 디렉토리 정보의 도움으로만 그렇게 할 수 있습니다. 다음 표는 모든 파일에 대해 32바이트의 루트 디렉토리 항목에 의해 저장된 정보를 보여줍니다.

루트 디렉토리 항목의 목차에서 볼 수 있듯이, 우리는 파일의 시작 및 종료 클러스터를 찾을 수 있습니다. 파일 이름의 첫 번째 바이트에는 파일에 대한 중요한 정보도 포함될 수 있습니다. 이 바이트가 제공하는 정보는 아래에 주어진 정보 중 하나일 수 있습니다.

루트 디렉토리 정보의 도움으로 1.44Mb, 3½ 인치 플로피 디스크에 저장된 모든 파일의 데이터를 지우기 위해 이 정보를 시도해 보겠습니다. 플로피 디스크의 데이터가 조각나지 않았다고 가정하면, 다음에 주어진 프로그램은 지정된 파일의 데이터를 데이터 영역에서 지웁니다.
/* 플로피 디스크의 지정된 파일의 데이터 영역을 지우는 프로그램 */
#include<stdio.h>
#include<dos.h>
///// 루트 디렉토리의 파일 항목 32바이트를 읽는 구조 \\\\\
구조체 루트
{
unsigned char filename[8]; /* 파일 이름 항목
8바이트 */
unsigned char extension[3]; /* 파일 확장자
3바이트 */
unsigned char 속성; /* 파일 속성 바이트 */
unsigned char reserved[10]; /* 예약된 바이트 10 */
unsigned int time; /* 시간, 2바이트 */
unsigned int date; /* 날짜, 2바이트 */
unsigned int starting_cluster;/* 파일 클러스터 시작,
2바이트 */
unsigned long file_size; /* 파일 크기(바이트),
4바이트 */
};
/* 모든 루트 디렉토리 항목을 읽으려면 이것을 사용해야 함 */
//구조체 루트 항목[224];
/* 루트 디렉토리의 한 섹터에 있는 모든 16개 파일 항목을 읽기 위한 구조 */
구조체 one_root_sector
{
구조체 루트 항목[16];
};
구조체 one_root_sector one;
void 메인()
{
int 결과, i, num_sectors,j;
char wipe_buf[512]; /* 지우는 데 사용할 데이터 버퍼
파일의 데이터 영역을 출력합니다 */
영어: clrscr();
result= absread(0x00, 1, 19, &one); /* 절대 섹터 읽기
19 (루트 디렉토리의 첫 번째 섹터) */
결과 != 0인 경우
{
perror("섹터 읽기 오류, 아무 키나 누르세요
출구...");
getch();
출구(1);
}
/* 루트 디렉토리에서 읽은 후 파일 정보 표시 */
printf("파일 번호 파일 이름 확장자 시작 클러스터
파일 크기 \n\n");
i=1;i<16;i++에 대하여
{
printf("\n %5d %8.8s %3.3s %5u %10lu ",
나, 하나의 항목[i].파일 이름, 하나의 항목[i].확장자,
one.entry[i].시작_클러스터, one.entry[i].파일_크기);
}
//// 파일을 삭제하기 위한 사용자 입력 받기 \\\\
printf("\n\n 삭제할 파일 번호를 입력하세요.
완전히 없애다 ");
scanf("%d", &i);
if(i<1 || i>15)
{
printf(" \"%d\"는 잘못된 선택입니다..., 아무거나 누르세요
"종료 키...", i);
getch();
출구(1);
}
///// 먼저 확인 후 계속 진행하세요 \\\\\\
printf("\n 당신은 곧 전멸할 것입니다,
파일 \"%.8s.%s\"",
one.entry[i].파일 이름,
하나.항목[i].확장);
printf("\n 계속하시겠습니까...(Y/N) ");
스위치(getche())
{
케이스 'y':
케이스 'Y':
부서지다;
기본:
종료(0);
}
///// 섹터별 파일 크기 계산 \\\\\
섹터 수 = 1.항목[i].파일_크기/512;
if((one.entry[i].파일_크기%512)>0)
{
섹터 수 = 섹터 수+1;
}
/* 512개의 NULL 문자가 포함된 512바이트 데이터 버퍼 */
j=0;j<512;j++에 대하여
{
닦아내기_버프[j] = '\0';
}
///// 파일의 시작 섹터 \\\\\
j = one.entry[i].시작_클러스터+31;
/* 파일 섹터가 끝날 때까지 데이터 영역을 지웁니다. */
(j!=(one.entry[i].starting_cluster +를 표시합니다.
섹터_수+31) )
{
if((abswrite(0x00, 1, j, &wipe_buf))!=0)
{
printf("\n 디스크 섹터에 쓰는 중 오류가 발생했습니다.");
얻다();
출력(0);
}
제이++;
}
printf("\n\n 파일 \"%.8s.%.3s\"이 삭제되었습니다!!!" ,
one.entry[i].파일_이름,
하나.항목[i].확장);
one.entry[i].속성 = 0; /* 파일 속성 설정
0으로 */
하나의 항목[i].시간 = 0; /* 시간 정보 지우기
파일 */
one.entry[i].date = 0; /* 날짜 정보 지우기
파일 */
one.entry[i].시작_클러스터 = 0; /* 초기 클러스터를 0으로 설정합니다.
*/
one.entry[i].파일_크기 = 0; /* 파일 크기를 0으로 설정 */
one.entry[i].filename[0]=0xE5; /* 원격을 제공
파일 상태 */
///// 위 정보를 루트 디렉토리에 기록합니다 \\\\\\
결과 = abswrite(0x00, 1, 19, &one);
결과 != 0인 경우
{
perror("섹터를 읽는 중 오류가 발생했습니다. 아무 키나 누르세요.
출구...");
얻다();
출력(1);
}
}
프로그램의 논리와 코딩에 대한 의견:
root 구조체는 루트 디렉토리의 파일 항목 32바이트를 읽는 데 사용되고, one_root_sector 구조체는 루트 디렉토리의 한 섹터에 있는 모든 16개 파일 항목을 읽습니다.
루트 디렉토리 정보의 모든 섹터를 읽으려면 struct root[224] 항목으로 가져와야 합니다. 하지만 저는 루트 디렉토리의 한 섹터에 대한 16개 레코드를 분석하는 프로그램을 작성했습니다.
파일의 시작 섹터는 다음과 같이 계산됩니다.
j = one.record[i].initial_cluster+31;
그 이유는 1.44MB, 3½ 인치 플로피 디스크의 데이터 영역이 디스크의 처음 32섹터 다음에 시작하기 때문입니다. 그리고 지정된 용량의 플로피 디스크에서는 하나의 클러스터가 하나의 섹터에 대응합니다.
다음 표는 1.44MB, 3½인치 플로피 디스크의 논리적 맵을 보여줍니다.

프로그램의 결과는 다음과 같이 표시됩니다.

여기서는 PARTBOOT.C 파일의 데이터를 삭제하고 지웠습니다. DIR 명령을 사용하여 플로피 디스크의 내용을 볼 때, PARTBOOT.C 파일은 거기에 표시되지 않습니다. 프로그램을 더 실행하면 삭제된 파일의 항목이 다음과 같이 표시됩니다.

여기서 ""(0xE5) 기호는 파일이 삭제되었음을 의미합니다. (파일 이름의 첫 글자는 표를 참조하세요).
하드 디스크에 동일한 프로그램을 작성하려면 루트 디렉토리가 있는 FAT를 사용하여 모든 파일의 데이터 영역에 대한 정보를 얻어야 합니다.
이는 오래된 파일이 삭제되고 새로운 파일이 생성되면서 하드 드라이브의 데이터 조각화 속도가 시간이 지남에 따라 증가하기 때문입니다. 그러면 디스크에 있는 모든 파일의 모든 데이터 클러스터가 데이터 영역에 연속적으로 남아 있을 필요가 없습니다. FAT에 액세스하면 모든 클러스터에 액세스할 수 있습니다.