【发布时间】:2023-03-13 06:32:01
【问题描述】:
我正在尝试使用SetFilePointerEx() 将磁盘的文件指针移动到特定偏移量(文件的最后一个簇)。计算出的偏移量是:
LARGE_INTEGER dist;
dist.QuadPart = (output1.QuadPart * dwBytesPerSect) + ((lastExtent + lengthOfExtent - 1) * totalClusterSize);
BOOL res = SetFilePointerEx(hDevice, dist, nullptr, FILE_BEGIN);
if (!res){
// handle error
DWORD error = GetLastError();
cout<<GetLastError()<<endl;
cout << "'There is an error with SetFilePointerEX" << endl;
}
cout<<"This is the SetFilePointer distance: \n\n"<<dist.QuadPart;
然后我使用Readfile() 读取最后一个 4k 簇块:
DWORD nRead;
unsigned char *buff;
buff = new unsigned char[totalClusterSize];
BOOL fileFromVol = ReadFile(hDevice, //C drive
buff,
4096,
&nRead,
NULL);
if (fileFromVol == 0){ //Error handling
cout << "Error with fileFromVol" << "\n\n";
DWORD error = GetLastError();
cout<<error<<endl;
if (error == ERROR_ACCESS_DENIED){
cout << "error_access_denied"<<endl;
}
}
cout<<"\n\n"<<buff<<"\n\n";
memset(buff,NULL,4096);
所以我的文件偏移量dist.QuadPart 始终保持不变,但每次我在同一个文件上运行我的程序时,我的读取缓冲区 (buff) 都会更改十六进制值。
首次运行示例:
This is the SetFilePointer distance:
3689362889266376704
008F4264
第二次运行示例:
This is the SetFilePointer distance:
3689362889266376704
00E53CE8
任何想法为什么它不断变化?
下一步,我需要将零写入集群。我可以使用memset() 在最后一个集群位置写零吗?
【问题讨论】:
-
不就是打印
buff[0]的地址吗?为什么每次都不会改变? -
我正在尝试从指定文件(如文本文件)的最后一个集群中读取数据,如果我不修改文件,数据不应该保持不变吗?
-
几点:您不应该将簇大小硬编码为 4096。您需要获取正在处理的卷的簇大小(每个簇的扇区数 * 每个扇区的字节数)和使用该值分配集群缓冲区并执行读取。此外,您的集群缓冲区是一个 4096
ints 的数组(x86 上是 16KB) - 它应该是一个字节数组。 -
您没有打印文件中的数据。您正在打印堆栈分配缓冲区的地址。由于各种因素(例如 ASLR),每次运行程序或调用函数时,该缓冲区的地址都会发生变化。
-
所以对于数组我应该使用 unsigned char [每个簇的扇区 * 每个扇区的字节数]?如何判断我是否从同一个文件句柄中读取数据?我的下一步是将数据写入文件偏移量,但我不想将数据写入错误的位置(系统文件)。