您好,欢迎来到测品娱乐。
搜索
您的当前位置:首页windows sdk编程系列文章29 --- 直接从硬盘扇区读取文件内容.

windows sdk编程系列文章29 --- 直接从硬盘扇区读取文件内容.

来源:测品娱乐


windows sdk编程系列文章 --- 直接从硬盘扇区读取文件内容 2008-09-05 15:43 理论:

基本概念就是通过文件句柄获取文件所在的簇列表。然后直接打开硬盘,根据簇所在的位置,直接读取文件数据。

方法1:可以通过打开\"\\\\\\\\.\\\\PHYSICALDRIVE0\",读取MBR,然后根据MBR中的DPT,找到活动分区的偏移,定位到DBR。然后将要定位簇的文件打开,获取文件句柄,将文件句柄传递给DeviceIoControl的FSCTL_GET_RETRIEVAL_POINTERS功能,就可以得到RETRIEVAL_POINTERS_BUFFER结构。

方法2:直接打开\"\\\\\\\\.\\\\c:\"就是定位到DBR了。然后跟上面同样的操作。 对于一些基本概念,MBR, DPT,DBR,以及fat32和ntfs的文件结构,可以参考下面的链接了解。

http://www.51stor.net/html/magnetism/200806/17-55.html 代码:(vc6, ntfs 见光盘DirectAccessFile #define _WIN32_WINNT 0x0400 #include #include #include

ULONGLONG *GetFileClusters(

PCHAR lpFileName, ULONG *ClusterSize, ULONG *ClCount, ULONG *FileSize {

HANDLE hFile; ULONG OutSize;

ULONG Bytes, Cls, CnCount, r; ULONGLONG *Clusters = NULL; BOOLEAN Result = FALSE; LARGE_INTEGER PrevVCN, Lcn; STARTING_VCN_INPUT_BUFFER InBuf; PRETRIEVAL_POINTERS_BUFFER OutBuf; CHAR Name[7]; DWORD SecPerCl; DWORD BtPerSec;

Name[0] = lpFileName[0]; Name[1] = ':'; Name[2] = 0;

GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL; *ClusterSize = SecPerCl * BtPerSec;

hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,

NULL, OPEN_EXISTING, 0, 0; if (hFile != INVALID_HANDLE_VALUE {

*FileSize = GetFileSize(hFile, NULL;

OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER + (*FileSize / *ClusterSize * sizeof(OutBuf->Extents;

OutBuf = (RETRIEVAL_POINTERS_BUFFER *malloc(OutSize; InBuf.StartingVcn.QuadPart = 0;

if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,

sizeof(InBuf, OutBuf, OutSize, &Bytes, NULL {

*ClCount = (*FileSize + *ClusterSize - 1 / *ClusterSize;

Clusters = (ULONGLONG *malloc(*ClCount * sizeof(ULONGLONG;

PrevVCN = OutBuf->StartingVcn;

for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++ {

Lcn = OutBuf->Extents[r].Lcn; for (CnCount = (ULONG(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart;

CnCount; CnCount--, Cls++, Lcn.QuadPart++

Clusters[Cls] = Lcn.QuadPart; PrevVCN = OutBuf->Extents[r].NextVcn; } }

free(OutBuf; CloseHandle(hFile; }

return Clusters; }

void Read(

PCHAR lpSrcName {

ULONG ClusterSize, BlockSize; ULONGLONG *Clusters;

ULONG ClCount, FileSize, Bytes; HANDLE hDrive; ULONG r; PVOID Buff; LARGE_INTEGER Offset;

CHAR Name[7];

Clusters = GetFileClusters(lpSrcName, &ClusterSize, &ClCount, &FileSize;

if (Clusters {

Name[0] = '\\\\'; Name[1] = '\\\\';

Name[2] = '.'; Name[3] = '\\\\';

Name[4] = lpSrcName[0]; Name[5] = ':'; Name[6] = 0;

hDrive = CreateFile(Name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0; if (hDrive != INVALID_HANDLE_VALUE {

Buff = malloc(ClusterSize;

for (r = 0; r < ClCount; r++, FileSize -= BlockSize

{

Offset.QuadPart = ClusterSize * Clusters[r];

SetFilePointer(hDrive, Offset.LowPart, &Offset.HighPart, FILE_BEGIN;

ReadFile(hDrive, Buff, ClusterSize, &Bytes, NULL;

BlockSize = FileSize < ClusterSize ? FileSize : ClusterSize; }

free(Buff;

CloseHandle(hDrive; }

free(Clusters;

} }

void main( {

Read(\"c:\\\\windows\\\\system32\\\\comctl32.dll\"; } 分析:

GetFileClusters 函数用于获取文件占用的簇列表,以及每个簇占用字节数,文件占用的簇数,文件大小等信息。这个函数中需要解释的一句就是

for (CnCount = (ULONG(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart;

CnCount; CnCount--, Cls++, Lcn.QuadPart++

Clusters[Cls] = Lcn.QuadPart; 这句循环用于生成簇列表。其中循环中的这一句是

CnCount = (ULONG(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart;

看msdn中的解释:红色部分就是说明了这句的含义。 RETRIEVAL_POINTERS_BUFFER

The RETRIEVAL_POINTERS_BUFFER structure is the output buffer for the FSCTL_GET_RETRIEVAL_POINTERS control code. typedef struct RETRIEVAL_POINTERS_BUFFER { DWORD ExtentCount; LARGE_INTEGER StartingVcn; struct {

LARGE_INTEGER NextVcn; LARGE_INTEGER Lcn; } Extents[1];

} RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER; Members ExtentCount

Count of elements in the Extents array. StartingVcn

Starting VCN returned by the function call. This is not

necessarily the VCN requested by the function call, as the file system driver may round down to the first VCN of the extent in which the requested starting VCN is found. Extents

Array of Extents structures. For the number of members in the array, see ExtentCount. Each member of the array has the following members. NextVcn

The VCN at which the next extent begins. This value minus either StartingVcn (for the first Extents array member or the NextVcn of the previous member of the array (for all other Extents array members is the length, in clusters, of the current extent. The length is an input to the FSCTL_MOVE_FILE operation. Lcn

The LCN at which the current extent begins on the volume. This value is an input to the FSCTL_MOVE_FILE operation. On the NTFS file system, the value (LONGLONG –1 indicates either a

compression unit that is partially allocated, or an unallocated region of a sparse file.

最后,注意一点,文件占用的簇是分组连续的。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- cepb.cn 版权所有 湘ICP备2022005869号-7

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务