仙人指路的编程乐园
留言簿 主人介绍 返回主页
Windows驱动 毕设 电子电路 电脑 PE外壳 心情 Windows应用程序 随笔 Web技术 加密算法 古老的DOS编程 杂项
通过EHCI访问U盘的代码
类别: 古老的DOS编程  上传时间: 2010-1-5 19:59:44  浏览(227)  留言(2) 
摘要:     添加这篇文章以纪念那年痛苦的经历,鼓舞我永远奋斗,战胜困难!

通过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;

}

 

上一篇: 文件监控(教学版)  下一篇: VC++写的故障录波查看分析软件


留言
2010-5-28 9:15:10
看Intel的手册最重要了
-- 仙人
 
查看全部留言



Copyright © 2009 BY MISSSIR,网站版权所有。 京ICP备09095257号

花褪残红青青杏小。燕子飞时,绿水人家绕。枝上柳绵吹又少。天涯何处无芳草。
墙里秋千墙外道。墙外行人,墙里佳人笑。笑渐不闻声渐悄。多情总被无情恼。

今年访问量 24091  今月访问量 651  今日访问量 54 

关于 您的地址
您的大名 您的邮箱
QQ/MSN/Tel 是否保密
留言内容