⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exfun.pas

📁 这是Virtual PC或VMWare虚拟机所创虚拟硬盘的文件读取程序.主要用到的是硬盘及分区格式的知识.因为VMware所创的硬盘文件最小为100M所以我没有测试,如果你测试不可用的话那我也没办法,
💻 PAS
字号:
{∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑
◎→
◎→                      Tresss Studio
◎→  Project: View HD File
◎→  Start Date:2006/1/18
◎→  Change Date:2006/1/28
◎→  System: Delphi6+WinXP
◎→  Author: Tresss
◎→  E-Mail: Tresss@sohu.com
◎→  Character: Main File,interface
◎→  Tips:此文件为主要功能实现单元;
◎→       供Main调用;
◎→
◎→
∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑∑}
unit ExFun;

interface

uses Main,Windows,Sysutils,Forms;

Procedure CheckFile;             //检查文件格式是否符合;
Procedure FileList;
Procedure FileSaveAs;

Var
  FStr,FLen:Array Of Integer;
implementation


Procedure CheckFile;
Var
  StrChk:Array [0..11] of Char;
  IntTmp:Integer;
Begin
  With FrmMain Do
  Begin
    If HFile<>0 Then FileClose(HFile);
    HFile:=FileOpen(EdtFile.Text,fmOpenRead);
    If HFile=INVALID_HANDLE_VALUE then
      raise Exception.Create('打开文件失败,可能是此文件正在使用!');
    IntTmp:=FileSeek(HFile,0,2);
    If IntTmp<16700000 Then           //小于16M的硬盘分区为Fat12格式,16M以上的才为Fat16格式;
      Raise Exception.Create('你的硬盘太小,至少要大于16M!');
    FileSeek(HFile,0,0);
    FileRead(HFile,StrChk,3);
    If StrChk<>'3缼' then
    Begin		//通过读取前三个字符来验证文件格式是否正确,此难方法不正确,但能用.
      raise Exception.Create('文件格式不正确!或此磁盘为空磁盘');
      Stb.Panels[0].Text:='无效磁盘!';
      Exit;
    End;
    FileSeek(HFile,454,0);
    FileRead(HFile,IntTmp,4);
    PosOfPart:=IntTmp*512;            //第一分区偏移
    IntTmp:=PosOfPart+54;
    FileSeek(HFile,IntTmp,0);
    FileRead(HFile,StrChk,5);
    StrChk[5]:=#0;
    If StrChk<>'FAT16' Then
    Begin
      raise Exception.Create('硬盘格式不正确!第一分区不是Fat16分区,分区应该大于16M');
      Stb.Panels[0].Text:='无法读取的磁盘!';
      Exit;
    End;
    FileSeek(HFile,-16,1);
    FileRead(HFile,StrChk,11);
    Stb.Panels[0].Text:='此分区卷标: '+StrChk;
    IntTmp:=PosOfPart+11;
    FileSeek(HFile,IntTmp,0);
    FileRead(HFile,SizeOfSector,2);
    FileRead(HFile,NumOfCluster,1);
    FileRead(HFile,NumOfResSec,2);
    FileRead(HFile,NumOfFat,1);
    FileRead(HFile,NumOfFile,2);
    FileRead(HFile,SizeOfPart,2);
    FileRead(HFile,StrChk,1);
    FileRead(HFile,IntTmp,2);
    SizeOfFat:=IntTmp*SizeOfSector;      //算出Fat区的大小;
    If SizeOfPart=0 Then  //扇区数太大,此处为0,则读取四字节记录处;
    Begin
      FileSeek(HFile,8,1);      //由0x15h移动到0x20h;
      FileRead(HFile,SizeOfPart,4);
    End;
    SizeOfPart:=SizeOfPart*SizeOfSector;
  End;
End;

Procedure FileList;
Var
  StrFile:Array[0..7] of char;
  StrTmp:String;
  IntTmp:Integer;
Begin
  With FrmMain Do
  Begin
    LbFile.Clear;
    SetLength(FStr,0);
    SetLength(FLen,0);    //算出根目录偏移;
    IntTmp:=PosOfPart+NumOfResSec*SizeOfSector+
      NumOfFat*SizeOfFat; //第一分区偏移加上分区保留扇区大小+Fat大小;
    FileSeek(HFile,IntTmp,0);
    FileRead(HFile,StrFile,8);
    StrTmp:=StrFile;
    FileRead(HFile,StrFile,3);
    StrFile[3]:=#0;
    If StrFile[0]>'''' Then
      StrTmp:=Trim(Trim(StrTmp)+'.'+StrFile);
    While StrTmp<>'' Do
    Begin
      FileRead(HFile,StrFile,1);
      IntTmp:=Ord(StrFile[0]);
      If IntTmp>31 Then IntTmp:=IntTmp-32;
      If IntTmp>15 Then StrTmp:=#229+StrTmp;    //忽略目录;
      If StrTmp[1]<>#229 Then     //已删除的文件;
      Begin
        IntTmp:=LbFile.Items.Count;
        SetLength(FStr,IntTmp+1);
        SetLength(FLen,IntTmp+1);
        FileSeek(HFile,14,1);
        FileRead(HFile,FStr[IntTmp],2);
        FileRead(HFile,FLen[IntTmp],4);
        LbFile.Items.Add(StrTmp);
      End
      Else
        FileSeek(HFile,20,1);
        FileRead(HFile,StrFile,8);
        StrTmp:=StrFile;
        FileRead(HFile,StrFile,3);
        If StrFile[0]>'''' Then
          StrTmp:=Trim(Trim(StrTmp)+'.'+StrFile[0]+StrFile[1]+StrFile[2]);
    End;
  End;
End;

Procedure FileSaveAs;
Var
  IntTmp,IntSmall,IntCurSize:Integer;   //文件不足一簇的数据大小,当前读取的大小;
  IntFatIndex:Integer;        //当前簇序号;
  Hfiles:THandle;
  FileTemp:Array [0..49] of char;
Begin
  With FrmMain Do
  Begin
    HFiles:=FileCreate(Sd1.FileName);
    If HFile=INVALID_HANDLE_VALUE then
    Begin
      raise Exception.Create('文件创建失败!');
      Exit;
    End;
    IntTmp:=FrmMain.LbFile.ItemIndex;
    IntFatIndex:=FStr[IntTmp];
    // 下面: 求出占不足一簇的数据的大小;
    IntSmall:=FLen[IntTmp] mod (NumOfCluster*SizeOfSector);
    IntTmp:=PosOfPart+NumOfResSec*SizeOfSector+IntFatIndex*2;
    FileSeek(HFile,IntTmp,0);
    FileRead(HFile,FileTemp,2);       //当前簇值;
    FileTemp[2]:=#0;
    //循环读出占整个簇的数据;
    While FileTemp<>#255#255 Do
    Begin         //算出数据区偏移;
      IntTmp:=PosOfPart+NumOfResSec*SizeOfSector+
      NumOfFat*SizeOfFat+NumOfFile*32+
      (IntFatIndex-2)*NumOfCluster*SizeOfSector;
      //上:  分区偏移+保留扇区大小+
      //Fat大小+目录区大小+
      //数据区当前簇具体数据偏移;
      FileSeek(HFile,IntTmp,0);
      IntCurSize:=50;
      IntTmp:=NumOfCluster*SizeOfSector;   //每簇大小;
      While IntTmp>0 Do   //将此簇数据写入保存的文件中;
      Begin
        If IntTmp<50 Then IntCurSize:=IntTmp;
        FileRead(HFile,FileTemp,IntCurSize);
        FileWrite(HFiles,FileTemp,IntCurSize);
        IntTmp:=IntTmp-50;
      End;
      //下面,算出Fat当前位置;
      IntTmp:=PosOfPart+NumOfResSec*SizeOfSector+IntFatIndex*2;
      FileSeek(HFile,IntTmp,0);
      FileRead(HFile,IntFatIndex,2);  //读取下一簇地址;
      IntTmp:=PosOfPart+NumOfResSec*SizeOfSector+IntFatIndex*2;
      FileSeek(HFile,IntTmp,0);
      Application.ProcessMessages;
      FileTemp[2]:=#0;
      FIleRead(HFile,FileTemp,2);   //判断是否整簇数据;
    End;

    IntCurSize:=50;//读取不足一簇的数据;
    IntTmp:=PosOfPart+NumOfResSec*SizeOfSector+
    NumOfFat*SizeOfFat+NumOfFile*32+
    (IntFatIndex-2)*NumOfCluster*SizeOfSector;
      //上:  算出数据地址;
    FileSeek(HFile,IntTmp,0);
    While IntSmall>0 Do
    Begin
      If IntSmall<50 Then IntCurSize:=IntSmall;
      FileRead(HFile,FileTemp,IntCurSize);
      FileWrite(HFiles,FileTemp,IntCurSize);
      Dec(IntSmall,50);
    End;                
    FileClose(Hfiles);
  End;
End;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -