#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <dir.h>
#include <stdlib.h>
#include <alloc.h>
#include <dos.h>
#include <time.h>
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
typedef struct
{
unsigned hund:7;
unsigned sec:6;
unsigned min:6;
unsigned hour:5;
} Time3Byte;
typedef struct tagENTRY
{
BYTE FileName[8];
BYTE FileExt[3];
BYTE Attrib;
BYTE Reserved;
Time3Byte TimeCreate;
WORD DateCreate;
WORD LastAccess;
WORD HightCluster;
WORD Time;
WORD Day;
WORD FirstCluster;
DWORD FileSize;
} ENTRY;
typedef struct tagBootSector
{
BYTE CmdJmp[3];
BYTE Ver[8];
WORD SectorSize;
BYTE SectorPerCluster;
WORD ReservedSector;
BYTE FatCount;
WORD RootSize;
WORD TotalSector;
BYTE Media;
WORD SectorPerFat;
WORD SectorPerTrack;
WORD HeadCount;
WORD HiddenSector;
BYTE Code[482];
} BootSector;
void ReadBootSector();
void ReadRDET();
int ReadSectors(int, int, void*);
int WriteSectors(int, int, void*);
void SetFatValue(int, int, unsigned char *);
void WriteFAT(BYTE *Fat);
void WriteRDET();
int MakeDir(char *path);
WORD IsExistPath(char *path);
void MakeEntryRoot(WORD FirstCluster,WORD ParrentCluster,char*buffer);
void MyStrCpy(char *,char*,int);
void UpperString(char *s);
ENTRY *RDET; // RDET pointer
BYTE *FAT; // FAT pointer
int numEntry; // Total entry of RDET
BootSector bootsector; // Boot sector
int main()
{
clrscr();
char command[256]={0};
ReadBootSector();
ReadRDET();
printf("Nhap vao duong dan thu muc can tao: ");
MakeDir(command);
getch();
return 0;
}
void ReadBootSector()
{
if(!ReadSectors(0,1,(void*)&bootsector))
{
printf("\nRead Boot Sector error"); getch();
exit(1);
}
}
void ReadRDET()
{
unsigned char RootSector;
// Total sector of RDET
RootSector=bootsector.RootSize/16;
// Total entry of RDET
numEntry=(RootSector*512)/sizeof(ENTRY);
// Alloc memory for RDET
RDET
=(ENTRY
*)malloc(numEntry
*sizeof(ENTRY
)); // Read RDET
if(!ReadSectors(19,RootSector,RDET))
{
getch();
exit(1);
}
}
//This function will create 2 entry: "." and ".." for SDET
void MakeEntryRoot(WORD FirstCluster,WORD ParrentCluster,ENTRY *SDET)
{
// entry .
SDET[0].FileName[0]=0x2E;
for(int i=1; i<8;i++) SDET[0].FileName[i]=0x20;
for(i=0; i<3;i++) SDET[0].FileExt[i]=0x20;
SDET[0].FirstCluster=FirstCluster;
SDET[0].TimeCreate=SetTime2(); // 3 byte
// SDET[0].Time= SetTime(); //2 byte
SDET[0].Day=SDET[0].DateCreate=SetDate();
// entry ..
SDET[1].FileName[0]=0x2E;
SDET[1].FileName[1]=0x2E;
for(i=2; i<11;i++) SDET[1].FileName[i]=0x20;
for(i=0; i<3;i++) SDET[1].FileExt[i]=0x20;
//If ParrentCluster = 0 : this folder is created in RDET
SDET[1].FirstCluster=ParrentCluster;
}
// This function will find the file in RDET or SDET
// If have, return 1
// else return 0;
// In: cluster contain SDET, or cluster =1 if RDET
int IsExistFile(WORD cluster, char *Name, char *Ext)
{
char *str;
if(cluster==1)
{
for(int entry=0; entry<224; entry++)
&& (strncmp(RDET
[entry
].
FileExt,Ext
,3)==0)) return RDET[entry].FirstCluster; // Already exist file
if(entry==224) return 0; // No file in RDET
}
else
{
ENTRY SDET[16];
//Read SDET
ReadSectors(cluster+31,1,(void*)&SDET);
for(int entry=2; entry<16; entry++)
&& (strncmp(SDET
[entry
].
FileExt,Ext
,3)==0)) return SDET[entry].FirstCluster; // Already exist file
if(entry==16) return 0; //No file in SDET
}
return cluster;
}
int MakeDir(char *path)
{
int clusFree;
ENTRY childSDET[16];
if((clusFree=FindClusterFree(2))==-1)
{
printf("Haven't enough free space"); return -1;
}
WORD cluster;
UpperString(path);
cluster=IsExistPath(path);
if(FindClusterFree(2)==-1)
{
printf("Haven't enough free space"); return -1;
}
//char buffer[512]={0};
if(cluster)
{
printf("The path is already exist !"); return -1;
}
else if (Direct.level==0) // ROOT DIR
for(int i=0; i<numEntry; i++)
{
if(RDET[i].FileName[0]==0)
{
UpperString(path);
MyStrCpy(RDET[i].FileName,path,11); //8 file name, 3 ext
RDET[i].Attrib=0x10; //dir
RDET[i].FirstCluster=clusFree;
RDET[i].TimeCreate=SetTime2();
RDET[i].Time=SetTime();
RDET[i].DateCreate=RDET[i].Day=SetDate();
SetFatValue(RDET[i].FirstCluster,0xFFF,FAT);
MakeEntryRoot(RDET[i].FirstCluster,Direct.cluster,childSDET);
WriteSectors(RDET[i].FirstCluster+31,1,(void*)childSDET); // Ghi vao first cluster
WriteFAT(FAT);
WriteRDET();
return 0;
}
}
else
{
ENTRY SDET[16]={0};
//Read SDET of cluster direct
ReadSectors(Direct.cluster+31,1,(void*)&SDET);
// mkEntryRoot(clusFree,Direct.cluster,(char*)SDET);
for(int i=2; i<16; i++)
//Update for parrent dir
if(SDET[i].FileName[0]==0)
{
MyStrCpy(SDET[i].FileName,path,11);
SDET[i].Attrib=0x10; //dir
SDET[i].FirstCluster=clusFree; // address of parrent dir
SDET[i].TimeCreate=SetTime2(); // time 3 byte
SDET[i].Time=SetTime();
SDET[i].DateCreate=SDET[2].Day=SetDate();
SetFatValue(SDET[2].FirstCluster,0xFFF,FAT);
if(!WriteSectors(Direct.cluster+31,1,(void*)&SDET))
printf("Write parrent SDET error");
// Create child dir
MakeEntryRoot(clusFree,Direct.cluster,childSDET);
SetFatValue(clusFree,0xFFF,FAT);
WriteFAT(FAT);
if(!WriteSectors(clusFree+31,1,(void*)childSDET))
printf("Write child SDET error");
return 0;
}
}
return -1; //error
}
void UpperString(char *s)
{
int i;
for (i
= 0; i
< strlen(s
); i
++) s[i+1]=0;
}
void MyStrCpy(char *s1,char *s2,int maxlen)
{
int i;
{
if(s2[i]==32 || s2[i]==0) s1[i]=32;
else s1[i] = s2[i];
}
if(i<maxlen)
for(i
=strlen(s2
); i
<maxlen
; i
++) s1[i]=32;
}
//Ham nay tim xem tren dia A co thu muc la path hay khong
//neu co tra ve cluster dau tien (2..n)
//neu khong tra ve 0
//neu rong tra ve 1 = root dir
WORD IsExistPath(char *path)
{
char temp[256],temp1[256];
int i;
WORD clus;
clus = 1;
Direct.level=0; // Mac dinh se~ la` o? Root
if (strlen(path
) == 0) return clus
; else
{
{
for (i
= 0; i
< strlen(temp
); i
++) // Find sub dir
if (temp[i] == '/' || temp[i] =='\\')
{
Direct.level++;
break;
}
{
path[0]=0;
return FindSubDir(clus,temp);
}
else
{
temp1[i] = 0;
clus = FindSubDir(clus,temp1);
if (clus == 0) return clus;
else
{
Direct.cluster=clus;
}
}
}
return clus;
}
}
void WriteRDET()
{
unsigned char RootSector;
RootSector=bootsector.RootSize/16;
if(!WriteSectors(19,RootSector,RDET))
{
getch();
exit(1);
}
}
void WriteFAT(BYTE *Fat)
{
if (!WriteSectors(1,9,(void *)Fat))
{
exit(1);
}
if (!WriteSectors(10,9,(void *)Fat))
{
exit(1);
}
}
int ReadSectors(int sector, int num, void*buffer)
{
union REGS inRegs, outRegs;
struct SREGS sRegs;
inRegs.h.al=0; //Drive A
inRegs.x.cx=num;
inRegs.x.dx=sector;
sRegs.ds=FP_SEG(buffer);
inRegs.x.bx=FP_OFF(buffer);
int86x(0x25,&inRegs,&outRegs,&sRegs);
if(outRegs.x.cflag) return 0;
return num;
}
int WriteSectors(int sector, int num, void *buffer)
{
union REGS inRegs, outRegs;
struct SREGS sRegs;
inRegs.h.al=0; //Drive A
inRegs.x.cx=num;
inRegs.x.dx=sector;
sRegs.ds=FP_SEG(buffer);
inRegs.x.bx=FP_OFF(buffer);
int86x(0x26,&inRegs,&outRegs,&sRegs);
if(outRegs.x.cflag) return 0;
return num;
}
void SetFatValue(int k, int value, unsigned char *Fat)
{
int i=(k*3)/2;
unsigned char nLo, nHi;
if((k%2)==0)
{
nHi=(value & 0xF00) >>8;
nLo=(value & 0xFF);
Fat[i]=nLo;
Fat[i+1]=(Fat[i+1] & 0xF0) | nHi;
}
else
{
nHi=(value& 0xFF0) >>4;
nLo=(value &0xF) <<4;
Fat[i]=(Fat[i] & 0xF)|nLo;
Fat[i+1]=nHi;
}
}