c - Windows 物理驱动器访问 fopen 和 fseek

标签 c windows file fseek

我目前正在尝试以 C 语言的二进制数据流的形式访问物理硬盘。我已经安装了一个图像 (.img),它可以从操作系统 (Win 7) 中读取。

我的 C 程序只是尝试以只读二进制模式打开物理驱动器,然后从驱动器中读取一些数据。

但是,如果我只是从流中读取数据而不去任何地方寻找,一切都很好,我取回了存储在驱动器中的数据,并且由于我在流中的偏移量为 0,所以我能够读取磁盘上的 MBR。

但是,如果我尝试 fseek 到距原点(零)的任何偏移量,fseek 将返回 -1,表明它无法执行此操作。

我猜这可能是访问物理磁盘的权限/ring 3/用户级问题,我可能不得不编写一个驱动程序来获得内核级访问权限来执行此操作,我只是感到困惑为什么我可以从第一个扇区读取一些数据,但我不能寻找任何其他偏移量。我在下面包含了我编写的 C 程序的一部分。

FILE *disk = fopen("\\\\.\\PhysicalDrive1, "rb+");
if (disk == NULL) {
    **error handle
 }
else { //Opened the drive sucessfully
fread(buffer, 1, 100, disk);
printf("Reading the first byte from buffer, it's:%d\n", buffer[0]);
//This works fine and I can read any byte within the initial buffer
int test = fseek(disk, 100, SEEK_SET);
printf("The value of fseek is:%d\n", test);
//This always returns -1, indicating the seek failed  
fclose(disk);
}

最佳答案

引自msdn:

如果成功,fseek 返回 0。否则,它返回一个非零值。在无法搜索的设备上,返回值为未定义。如果 stream 是一个空指针,或者如果 origin 不是下面描述的允许值之一,fseek 调用无效参数处理程序,如参数验证中所述。如果允许执行继续,这些函数将 errno 设置为 EINVAL 并返回 -1。

C 标准 [ISO/IEC 9899:2011] 的第 7.21.9.2 节指定以二进制模式打开二进制文件时 fseek() 的以下行为:

A binary stream need not meaningfully support fseek calls with a whence value of SEEK_END.

另外,Section 7.21.3 的脚注 268 是这样说的:

Setting the file position indicator to end-of-file, as with fseek(file, 0, SEEK_END), has undefined behavior for a binary stream (because of possible trailing null characters) or for any stream with state-dependent encoding that does not assuredly end in the initial shift state.

很多底层的东西都很重要,比如扇区对齐、文件系统等。这需要一个特定的驱动程序来帮助在驱动器中导航,也需要考虑。

希望这对您有所帮助。

关于c - Windows 物理驱动器访问 fopen 和 fseek,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14506952/

相关文章:

c - 将硬盘上文件中的空格替换为 %20

java - JFileChooser 返回错误的文件名?

c - ESP8266 GPIO 16 不能用作按钮

c - 在 C 中使用 OpenSSL 加密字符串

java - C 指针 - 从 Char 到 Char 的无效转换*

c++ - 如何获取驱动器 GUID 值?

python - 'unlink()' does not work in Python' s shared_memory on Windows

java - 正在解压缩 zip 文件...找不到文件异常

c++ - 为函数定义符号不明确的指针参数

c++ - 从不同线程调用的 XInputGetState 和 XInputSetState