通过EHCI访问U盘的代码
//创建qTD
TqTD* CreateQTD()
{
//申请空间,并按32字节对齐
DWORD malloc_addr = (DWORD)malloc(sizeof(TqTD) + 32);
DWORD line_addr1 = GetLineAddr(malloc_addr);
line_addr1 = (line_addr1 + 32) & 0xFFFFFFE0L;
TqTD* td = (TqTD*)GetProgAddr(line_addr1);
td->malloc_ptr = malloc_addr;
return td;
}
//创建一个QH结构
TQueueHead* CreateQueueHead()
{
//申请空间,并按32字节对齐
DWORD malloc_addr = (DWORD)malloc(sizeof(TQueueHead) + 32);
DWORD line_addr1 = GetLineAddr(malloc_addr);
line_addr1 = (line_addr1 + 32) & 0xFFFFFFE0L;
TQueueHead* qh = (TQueueHead*)GetProgAddr(line_addr1);
qh->malloc_ptr = malloc_addr;
return qh;
}
//初始化异步队列
void InitAsynchronous()
{
pQH0 = CreateQueueHead();
pQH_OUT = CreateQueueHead();
pQH_IN = CreateQueueHead();
pQH0->link = GetLineAddr((DWORD)pQH_OUT) | 0x00000002L; //建立一个圈
pQH_OUT->link = GetLineAddr((DWORD)pQH_IN) | 0x00000002L;
pQH_IN->link = GetLineAddr((DWORD)pQH0) | 0x00000002L;
ReInitQHs();
pTD_EP0 = CreateQTD();
pTD_CBW = CreateQTD();
pTD_CSW = CreateQTD();
pTD_OUT = CreateQTD();
pTD_IN = CreateQTD();
ReInitQTDs();
DWORD line_addr = GetLineAddr((DWORD)pQH0);
*ASYNCLISTADDR = line_addr;
}
//初始化周期队列
void InitPeriodicSchedule()
{
//只申请空间了,没有释放
DWORD prog_addr1 = (DWORD)malloc(1024 * 8);
DWORD line_addr1 = GetLineAddr(prog_addr1);
DWORD line_addr2 = (line_addr1 + 0x00001000L) & 0xFFFFF000L; //4K字节对齐
DWORD* prog_addr2 = (DWORD*)GetProgAddr(line_addr2);
//printf("Periodic Schedule: \n");
//printf("prog_addr1 = %08lX \n", prog_addr1);
//printf("line_addr1 = %08lX \n", line_addr1);
//printf("line_addr2 = %08lX \n", line_addr2);
//printf("prog_addr2 = %08lX \n", prog_addr2);
//getch();
for(int i = 0; i < 1024; i++)
{
*prog_addr2 = 0xFFFFFFFFL;
prog_addr2++;
}
*PERIODICLISTBASE = line_addr2;
}
//SETUP(0)
void EP0_SETUP()
{
//SETUP(0)
SetQtd_Active(pTD_EP0);
SetQtd_Pid(pTD_EP0, PID_SETUP);
SetQtd_Bytes(pTD_EP0, 8);
SetQtd_Dt(pTD_EP0, 0);
pTD_EP0->buf0 = GetLineAddr((DWORD)(&DevReq));
pTD_EP0->next |= 1;
pQH0->next_qtd = GetLineAddr((DWORD)pTD_EP0);
WaitTdSend(pTD_EP0);
//printf(" * EP0_SETUP complete");
delay(10);
}
//IN(1)
void EP0_IN(WORD len)
{
//IN(1)
SetQtd_Active(pTD_EP0);
SetQtd_Pid(pTD_EP0, PID_IN);
SetQtd_Bytes(pTD_EP0, len);
SetQtd_Dt(pTD_EP0, 1);
pTD_EP0->buf0 = GetLineAddr((DWORD)Buf_In);
pTD_EP0->next |= 1;
pQH0->next_qtd = GetLineAddr((DWORD)pTD_EP0);
WaitTdSend(pTD_EP0);
//printf(" * EP0_IN complete");
delay(10);
}
//OUT(1)
void EP0_OUT()
{
//OUT(1)
SetQtd_Active(pTD_EP0);
SetQtd_Pid(pTD_EP0, PID_OUT);
SetQtd_Bytes(pTD_EP0, 0);
SetQtd_Dt(pTD_EP0, 1);
pTD_EP0->buf0 = GetLineAddr((DWORD)Buf_Out);
pTD_EP0->next |= 1;
pQH0->next_qtd = GetLineAddr((DWORD)pTD_EP0);
WaitTdSend(pTD_EP0);
//printf(" * EP0_OUT complete");
delay(10);
}
//读设备描述符
void ReadDevDescriptor()
{
//设备请求
DevReq.bReqType = 0x80;
DevReq.bRequest = 0x06;
DevReq.wValue = 0x0100;
DevReq.wIndex = 0;
DevReq.wLength = 18;
EP0_SETUP();
EP0_IN(18);
EP0_OUT();
printf("\n-------USB DEVICE DESCRIPTOR-------\n");
for(int i = 0; i < 18; i++)
{
printf("%02X ", Buf_In[i]);
}
}
//读配置描述符
void ReadConfigDescriptor()
{
//设备请求
DevReq.bReqType = 0x80;
DevReq.bRequest = 0x06;
DevReq.wValue = 0x0200;
DevReq.wIndex = 0;
DevReq.wLength = 9;
EP0_SETUP();
EP0_IN(9);
EP0_OUT();
printf("\n-------USB CONFIG DESCRIPTOR-------\n");
for(int i = 0; i < 9; i++)
{
printf("%02X ", Buf_In[i]);
}
WORD total_length = Buf_In[3] * 256 + Buf_In[2];
printf("\n total length: %d \n", total_length);
DevReq.bReqType = 0x80;
DevReq.bRequest = 0x06;
DevReq.wValue = 0x0200;
DevReq.wIndex = 0;
DevReq.wLength = total_length;
EP0_SETUP();
EP0_IN(total_length);
EP0_OUT();
printf("\n-------ALL CONFIG DESCRIPTOR-------\n");
for(int i = 0; i < total_length; i++)
{
printf("%02X ", Buf_In[i]);
}
}
void SendTD_CBW()
{
DWORD len = (DWORD)sizeof(cbw) << 16;
//pTD_CBW->token = OutDt|len;
//ReverseOutDt();
pTD_CBW->token = len;
SetQtd_Active(pTD_CBW);
SetQtd_Pid(pTD_CBW, PID_OUT);
pTD_CBW->buf0 = GetLineAddr((DWORD)(&cbw));
//printf(" * pTD_CBW->token: %08lX", pTD_CBW->token);
pTD_CBW->next = 1L;
pQH_OUT->next_qtd = GetLineAddr((DWORD)pTD_CBW);
//printf(" * wait pTD_CBW");
WaitTdSend(pTD_CBW);
//printf(" * pTD_CBW complete");
}
void SendTD_CSW()
{
DWORD len = (DWORD)sizeof(csw) << 16;
//pTD_CSW->token = InDt|len;
//ReverseInDt();
pTD_CSW->token = len;
SetQtd_Active(pTD_CSW);
SetQtd_Pid(pTD_CSW, PID_IN);
pTD_CSW->buf0 = GetLineAddr((DWORD)(&csw));
//printf(" * pTD_CSW->token: %08lX", pTD_CSW->token);
pTD_CSW->next = 1L;
pQH_IN->next_qtd = GetLineAddr((DWORD)pTD_CSW);
//printf(" * wait pTD_CSW");
WaitTdSend(pTD_CSW);
//printf(" * pTD_CSW complete");
}
void SendTD_IN()
{
DWORD len = cbw.dTransferLength << 16;
//pTD_IN->token = InDt|len;
//ReverseInDt();
pTD_IN->token = len;
SetQtd_Active(pTD_IN);
SetQtd_Pid(pTD_IN, PID_IN);
pTD_IN->buf0 = GetLineAddr((DWORD)Buf_Bulk);
//printf(" * pTD_IN->token: %08lX", pTD_IN->token);
pTD_IN->next = 1L;
pQH_IN->next_qtd = GetLineAddr((DWORD)pTD_IN);
//printf(" * wait pTD_IN");
WaitTdSend(pTD_IN);
//printf(" * pTD_IN complete");
}
void SendTD_OUT()
{
DWORD len = cbw.dTransferLength << 16;
//pTD_OUT->token = OutDt|len;
//ReverseOutDt();
pTD_OUT->token = len;
SetQtd_Active(pTD_OUT);
SetQtd_Pid(pTD_OUT, PID_OUT);
pTD_OUT->buf0 = GetLineAddr((DWORD)Buf_Bulk);
//printf(" * pTD_OUT->token: %08lX", pTD_IN->token);
pTD_OUT->next = 1L;
pQH_OUT->next_qtd = GetLineAddr((DWORD)pTD_OUT);
//printf(" * wait pTD_OUT");
WaitTdSend(pTD_OUT);
//printf(" * pTD_OUT complete");
}
//USB标准请求-选择配置
void SetConfiguration(WORD value)
{
//printf(" * SetConfiguration()");
DevReq.bReqType = 0x00;
DevReq.bRequest = 9;
DevReq.wValue = value;
DevReq.wIndex = 0;
DevReq.wLength = 0;
EP0_SETUP();
EP0_IN(0);
//printf(" * OK");
}
//USB标准请求-选择接口
void SetInterface(WORD index)
{
//printf(" * SetInterface()");
DevReq.bReqType = 0x01;
DevReq.bRequest = 11;
DevReq.wValue = 0;
DevReq.wIndex = index;
DevReq.wLength = 0;
EP0_SETUP();
EP0_IN(0);
//printf(" * OK");
}
void EhciPortConnect()
{
printf(" * EhciPortConnect()");
ReadDevDescriptor();
ReadConfigDescriptor();
SetConfiguration(1);
SetInterface(0);
//OutDt=0;
//InDt=0;
cbw.dTag=0;
ScsiCmdInit();
InitUDFat();
printf(" * usb has connected");
}
//UFI命令读
void UfiRead(DWORD lba)
{
//printf(" * UfiRead(%08lX)", lba);
BYTE * pByte;
cbw.dTransferLength = 512;
cbw.bLUN = 0;
cbw.bCBLength = 0x0c;
cbw.bmFlags = CBW_DATA_IN;
cbw.CommandBlock[0] = SCSI_CMD_READ_10;
pByte=(BYTE*)&lba;
cbw.CommandBlock[1] = 0;
cbw.CommandBlock[2] = pByte[3];
cbw.CommandBlock[3] = pByte[2];
cbw.CommandBlock[4] = pByte[1];
cbw.CommandBlock[5] = pByte[0];
cbw.CommandBlock[6] = 0;
cbw.CommandBlock[7] = 0;
cbw.CommandBlock[8] = 1;
cbw.CommandBlock[9] = 0;
cbw.CommandBlock[10] = 0;
cbw.CommandBlock[11] = 0;
cbw.dTag++;
SendTD_CBW();
SendTD_IN();
SendTD_CSW();
//printf(" * UfiRead OK");
}
//UFI命令写
void UfiWrite(DWORD lba)
{
//printf(" * UfiWrite(%08lX)", lba);
BYTE * pByte;
cbw.dTransferLength = 512;
cbw.bLUN = 0;
cbw.bCBLength = 0x0c;
cbw.bmFlags = CBW_DATA_OUT;
cbw.CommandBlock[0] = SCSI_CMD_WRITE_10;
pByte=(BYTE*)&lba;
cbw.CommandBlock[1] = 0;
cbw.CommandBlock[2] = pByte[3];
cbw.CommandBlock[3] = pByte[2];
cbw.CommandBlock[4] = pByte[1];
cbw.CommandBlock[5] = pByte[0];
cbw.CommandBlock[6] = 0;
cbw.CommandBlock[7] = 0;
cbw.CommandBlock[8] = 1;
cbw.CommandBlock[9] = 0;
cbw.CommandBlock[10] = 0;
cbw.CommandBlock[11] = 0;
cbw.dTag++;
SendTD_CBW();
SendTD_OUT();
SendTD_CSW();
//printf(" * UfiWrite OK");
}
//读FAT32分区的信息
void GetFatInfo()
{
printf(" * GetFatInfo()");
//磁盘分区表
UfiRead(0);
fat.Type = Buf_Bulk[446 + 4];
fat.LbaStart = *((DWORD*)(Buf_Bulk + 446 + 8));
fat.LbaSize = *((DWORD*)(Buf_Bulk + 446 + 12));
printf(" * Type=%02X, ", fat.Type);
printf("LbaStart=%08lX, ", fat.LbaStart);
printf("LbaSize=%08lX, ", fat.LbaSize);
//分区的第一个扇区BPB
UfiRead(fat.LbaStart);
fat.SecPerClus = Buf_Bulk[13];
fat.RsvdSecCnt = *((WORD*)(Buf_Bulk + 14));
fat.NumFATs = Buf_Bulk[16];
fat.TotSec32 = *((DWORD*)(Buf_Bulk + 32));
fat.FATSz32 = *((DWORD*)(Buf_Bulk + 36));
fat.RootClus = *((DWORD*)(Buf_Bulk + 44));
fat.FSInfo = *((WORD*)(Buf_Bulk + 48));
printf("SecPerClus=%02X, ", fat.SecPerClus);
printf("RsvdSecCnt=%04X, ", fat.RsvdSecCnt);
printf("NumFATs=%02X, ", fat.NumFATs);
printf("TotSec32=%08lX, ", fat.TotSec32);
printf("FATSz32=%08lX, ", fat.FATSz32);
printf("RootClus=%08lX, ", fat.RootClus);
printf("FSInfo=%04X, ", fat.FSInfo);
//FAT表的起始扇区
fat.FatStart = fat.RsvdSecCnt + fat.LbaStart;
//数据区起始扇区
fat.DatStart = fat.FatStart + fat.FATSz32 * fat.NumFATs;
//总的簇数
fat.NumClus = (fat.TotSec32 - fat.RsvdSecCnt - fat.FATSz32 * fat.NumFATs) / fat.SecPerClus;
//FsInfo所在的扇区号,从磁盘0扇区开始
fat.FsLba = fat.FSInfo + fat.LbaStart;
printf("FatStart=%08lX, ", fat.FatStart);
printf("DatStart=%08lX, ", fat.DatStart);
printf("NumClus=%08lX, ", fat.NumClus);
printf("FsLba=%08lX, ", fat.FsLba);
//读FSInfo
ReadFsInfo();
}
//---------------------------------------------------------
//功能: 把文件名转变成11个字节8.3格式
//参数: name1 - 以0结束,文件名8位,后缀3位
// name2 - 11个字节
// tail - 字符串结束符
//返回值:
//说明: name1 --> name2, 假设name1是合法的
//
void FormatDirName(char* name1, char* name2)
{
//printf(" * FormatDirName()");
int k2 = 0;
while((*name1 != '\\') && (*name1 != 0))
{
if((*name1 >= 'a') && (*name1 <= 'z'))
{
name2[k2] = *name1 - 32;
name1++;
k2++;
}
else if(*name1 == '.') //该变后缀名了
{
while(k2 < 8)
{
name2[k2] = ' ';
k2++;
}
name1++;
}
else
{
name2[k2] = *name1;
name1++;
k2++;
}
}
while(k2 < 11)
{
name2[k2] = ' ';
k2++;
}
}
//功能: 查找一级目录
//参数: clus - 28位
// pos - (返回)目录项在磁盘上的位置
// pEntry - 返回目录项的内容
//返回值: 找到了true
//说明: 在clus链中找
bool SearchDirOrFile(char* dir_name, DWORD clus, TDirEntry* pEntry, TDiskPos* pos)
{
printf(" * SearchDirOrFile()");
//printf(" * SearchDirOrFile(clus=%08lX)", clus);
DWORD fst_sec; //扇区号
TDirEntry* pDir; //指向目录项的指针
int i, k;
while(clus > 1 && clus < 0x0FFFFFF0L)
{
fst_sec = GetFstSecOfClus(clus);
for(i = 0; i < fat.SecPerClus; i++)
{
UfiRead(fst_sec + i);
for(k = 0; k < 512; k += 32)
{
pDir = (TDirEntry*)(Buf_Bulk + k);
if(pDir->Name[0] == 0) //到达目录列表结束
{
return false;
}
if(CmpDirName(pDir, dir_name))
{
*pEntry = *pDir;
pos->lba = fst_sec + i;
pos->off = k;
return true;
}
}
}
clus = GetNextClus(clus);
}
return false;
}
//分配簇
DWORD AllocClus()
{
printf(" * AllocClus()");
DWORD new_clus = fs.Nxt_Free;
//空闲扇区在FAT表中的位置
DWORD sec = GetSec_FatItem(new_clus);
WORD off = GetOff_FatItem(new_clus);
DWORD i;
DWORD* p; //指向FAT Item的指针
UfiRead(sec);
for(i = 0; i < fat.NumClus; i++)
{
p= (DWORD*)(Buf_Bulk + off);
if((*p & 0x0FFFFFFFL) == 0L) //找到了
{
//把这一项标记为文件的最后一簇
*p |= 0x0FFFFFFFL;
UfiWrite(sec);
break;
}
//移到下一个位置
off += 4 ;
if(off >= 512)
{
off = 0;
sec++;
if((sec - fat.FatStart) >= fat.FATSz32)
sec -= fat.FATSz32;
UfiRead(sec);
}
new_clus++;
}
//假设一定可以找到
if((new_clus - 2) >= fat.NumClus)
new_clus -= fat.NumClus;
//修改FSInfo结构
fs.Nxt_Free = new_clus + 1;
if((fs.Nxt_Free - 2) >= fat.NumClus)
fs.Nxt_Free -= fat.NumClus;
fs.Free_Count -= 1;
WriteFsInfo();
return new_clus;
}
//功能: 释放簇
//返回值:clus连接的下一个clus
DWORD FreeClus(DWORD clus)
{
printf(" * FreeClus()");
DWORD sec = GetSec_FatItem(clus);
WORD off = GetOff_FatItem(clus);
UfiRead(sec);
DWORD* p = (DWORD*)(Buf_Bulk + off);
DWORD next_clus = *p & 0x0FFFFFFFL;
*p &= 0xF0000000L;
UfiWrite(sec);
fs.Free_Count--;
return next_clus;
}
//功能: 删除文件或者目录
//参数: pos - 目录项入口在磁盘上的位置
//说明: 把删除目录简单化了,其实这样是错误的,但是我就这样
void DeleteDirOrFile(TDiskPos pos)
{
printf(" * DeleteDirOrFile()");
//目录项变成空
UfiRead(pos.lba);
TDirEntry* p = (TDirEntry*)(Buf_Bulk + pos.off);
DWORD clus = GetSubClusOfDir(p);
p->Name[0] = 0xE5;
p++;
if((p->Attr & 0x0F) == 0x0F)
{
p->Name[0] = 0xE5;
}
UfiWrite(pos.lba); //写回磁盘
//文件内容变成空
while((clus > 1L) && (clus < 0x0FFFFFF0L))
{
clus = FreeClus(clus);
}
WriteFsInfo();
}
//功能: 在clus簇链中创建一个目录项(不具体指目录还是文件)
//参数: clus - 在这个簇链中查找
// pos - (返回)新创建的这个目录项在磁盘中的位置
//返回值: 这个目录指向的簇
//说明: 清空一个目录项之后,让目录项指到一个空簇上
bool AllocDirOrFile(DWORD clus, TDiskPos* pos)
{
printf(" * AllocDirOrFile()");
DWORD fst_sec; //新建的目录项所在的扇区号
TDirEntry* pDir; //指向目录项的指针
WORD i, k, n;
DWORD clus2;
while(clus > 1 && clus < 0x0FFFFFF0L) //循环每一簇
{
fst_sec = GetFstSecOfClus(clus);
for(i = 0; i < fat.SecPerClus; i++) //循环每个扇区
{
UfiRead(fst_sec + i);
for(k = 0; k < 512; k += 32) //扇区中每个目录项
{
pDir = (TDirEntry*)(Buf_Bulk + k);
if((pDir->Name[0] == 0xE5) || (pDir->Name[0] == 0xE5) || (pDir->Name[0] == 0))
{
//找到一个空位置,这样最好了,不用再分配
clus2 = AllocClus();
//设置簇指向, 写回磁盘
UfiRead(fst_sec + i);
for(n = 0; n < 32; n++)
{
Buf_Bulk[k + n] = 0;
}
SetSubClusOfDir(pDir, clus2);
UfiWrite(fst_sec + i);
pos->lba = fst_sec + i;
pos->off = k;
if(pDir->Name[0] == 0)
{
//再分配一个结束项
if(k < 480)
{
k += 32;
UfiRead(fst_sec + i);
for(n = 0; n < 32; n++)
{
Buf_Bulk[k + n] = 0;
}
UfiWrite(fst_sec + i);
}
else if(i < (fat.SecPerClus - 1))
{
i++;
UfiRead(fst_sec + i);
for(n = 0; n < 32; n++)
{
Buf_Bulk[n] = 0;
}
UfiWrite(fst_sec + i);
}
else
{
clus2 = AllocClus();
AppendNewClus(clus, clus2);
fst_sec = GetFstSecOfClus(clus2);
UfiRead(fst_sec);
for(n = 0; n < 32; n++)
{
Buf_Bulk[n] = 0;
}
UfiWrite(fst_sec);
}
}
return true;
}
}
}
clus = GetNextClus(clus);
}
return false;
}
//功能: 打开文件
//参数: path - 文件的路径
// uf - (返回)文件在磁盘上的位置
//说明: 假设文件的路径完全合法
bool UFileOpen(char* path, TUsbFile* uf)
{
printf("\n UFileOpen()");
int i;
//--begin--------------------------
//
//看看几级目录,把每一层目录都放到那个数组里面
//
int depth = 0;
char* p = path;
while(*p != 0)
{
if(*p == '\\')
depth++;
p++;
}
char* dir_list = (char*)malloc(depth * 11 + 1);
dir_list[depth * 11] = 0;
p = path;
for(i = 0; i < depth; i++)
{
while(*p != '\\') p++;
p++;
FormatDirName(p, dir_list + i * 11);
}
//--end----------------------------
//一级一级地去创建
DWORD clus = fat.RootClus; //从这个簇中查找
TDiskPos dir_pos;
TDirEntry entry; //保存找到的目录项
for(i = 0; i < depth; i++) //一层目录一层目录地创建
{
if(SearchDirOrFile(dir_list + 11 * i, clus, &entry, &dir_pos))
{
if(i < depth - 1)
{
//如果找到了,但找到的不是目录
if((entry.Attr & 0x10) != 0x10)
{
delete[] dir_list;
return false;
}
}
else //如果正在找文件
{
//如果找到了,但找到的不是文件
if((entry.Attr & 0x10) == 0)
{
uf->EntrySec = dir_pos.lba;
uf->EntryOff = dir_pos.off;
uf->theClus = GetSubClusOfDir(&entry);
uf->theSecInClus = 0;
free(dir_list);
return true;
}
}
}
clus = GetSubClusOfDir(&entry);
}
free(dir_list);
return false;
}
//功能: 创建文件
//说明: 假设文件的路径完全合法
bool UFileCreate(char* path, TUsbFile* uf)
{
printf("\n UFileCreate()");
int i, k;
//--begin--------------------------
//
//看看几级目录,把每一层目录都放到那个数组里面
//
int depth = 0;
char* p = path;
while(*p != 0)
{
if(*p == '\\')
depth++;
p++;
}
char* dir_list = (char*)malloc(depth * 11 + 1);
dir_list[depth * 11] = 0;
p = path;
for(i = 0; i < depth; i++)
{
while(*p != '\\') p++;
p++;
FormatDirName(p, dir_list + i * 11);
}
//--end----------------------------
//printf("\n fat.RootClus=%08lX ", fat.RootClus);
//一级一级地去创建
DWORD clus = fat.RootClus; //从这个簇中查找
DWORD sub_clus;
TDiskPos dir_pos;
TDirEntry* pDir; //保存找到的目录项
TDirEntry entry; //保存找到的目录项
bool is_find; //是否真的找到
bool need_search = true; //需要查找
DWORD sec; //扇区号
for(i = 0; i < depth; i++) //一层目录一层目录地创建
{
//printf("\n 1 for clus=%08lX ", clus);
is_find = false;
if(need_search && SearchDirOrFile(dir_list + 11 * i, clus, &entry, &dir_pos))
{
//printf("\n find one, entry.Attr=%02X, lba=%08lX, off=%04X", entry.Attr, dir_pos.lba, dir_pos.off);
//getch();
if((i < depth - 1) && ((entry.Attr & 0x10) == 0x10))
{
//真的找到了
is_find = true;
}
else
{
//最后的文件,或者应该是目录的时候不是目录
DeleteDirOrFile(dir_pos);
}
}
if(is_find)
{
//如果找到,继续找下一级
sub_clus = GetSubClusOfDir(&entry);
}
else //没有找到,就创建(目录或者文件)
{
//以后的路径也不需要查找了
need_search = false;
//分配一个空的文件或者目录
AllocDirOrFile(clus, &dir_pos);
//printf("\n after AllocDirOrFile() lba=%08lX, off=%04X", dir_pos.lba, dir_pos.off);
//getch();
UfiRead(dir_pos.lba);
pDir = (TDirEntry*)(Buf_Bulk + dir_pos.off);
sub_clus = GetSubClusOfDir(pDir); //文件或者目录指向的簇
//写上名字和属性
CopyDirName((char*)(pDir->Name), dir_list + i * 11);
pDir->Attr = (i < depth - 1) ? 0x10 : 0; //目录 or 文件
UfiWrite(dir_pos.lba);
if(i < depth - 1) //如果创建的是目录
{
sec = GetFstSecOfClus(sub_clus);
UfiRead(sec);
for(k = 0; k < 512; k ++)
Buf_Bulk[k] = 0;
//第一个目录项
pDir = (TDirEntry*)Buf_Bulk;
CopyDirName((char*)(pDir->Name), ". ");
SetSubClusOfDir(pDir, sub_clus);
//第二个目录项
pDir++;
CopyDirName((char*)(pDir->Name), ".. ");
SetSubClusOfDir(pDir, clus);
UfiWrite(sec);
}
else //如果创建的是文件,最后一个一定是文件
{
uf->EntrySec = dir_pos.lba;
uf->EntryOff = dir_pos.off;
uf->theClus = sub_clus;
uf->theSecInClus = 0;
free(dir_list);
return true;
}
}
clus = sub_clus;
}
free(dir_list);
return false;
}
//参数: uf - 要写的文件指针
// buf - 要把这里面的东西写进去
// SecNum -要读几个扇区,扇区大小是512字节
bool UFileRead(TUsbFile* uf, BYTE* buf, int SecNum)
{
printf("\n UFileRead()");
int i, k;
DWORD fst_sec;
for(i = 0; i < SecNum; i++)
{
if((uf->theClus <= 1L) || (uf->theClus >= 0x0FFFFFF0L)) //文件已经结束了,还要读
return false;
//先读进来再说
fst_sec = GetFstSecOfClus(uf->theClus);
UfiRead(fst_sec + uf->theSecInClus);
for(k = 0; k < 512; k++)
{
buf[i * 512 + k] = Buf_Bulk[k];
}
//然后转到下一个扇区
uf->theSecInClus++;
if(uf->theSecInClus >= fat.SecPerClus)
{
uf->theClus = GetNextClus(uf->theClus);
uf->theSecInClus = 0;
}
}
return true;
}
//参数: uf - 要写的文件指针
// buf - 要把这里面的东西写进去
// SecNum -要写几个扇区,扇区大小是512字节
bool UFileWrite(TUsbFile* uf, BYTE* buf, int SecNum)
{
printf("\n UFileWrite()");
int i, k;
DWORD fst_sec = GetFstSecOfClus(uf->theClus);
DWORD new_clus;
for(i = 0; i < SecNum; i++) //写100个扇区
{
//先写进去
for(k = 0; k < 512; k++)
{
Buf_Bulk[k] = buf[i * 512 + k];
}
UfiWrite(fst_sec + uf->theSecInClus);
//然后转到下一个扇区
uf->theSecInClus++;
if(uf->theSecInClus >= fat.SecPerClus)
{
new_clus = AllocClus();
AppendNewClus(uf->theClus, new_clus);
uf->theClus = new_clus;
uf->theSecInClus = 0;
fst_sec = GetFstSecOfClus(uf->theClus);
}
}
return true;
}