gpt4 book ai didi

winapi - 从物理硬盘读取数据

转载 作者:太空宇宙 更新时间:2023-11-04 12:47:17 28 4
gpt4 key购买 nike

我正在尝试开发一个程序,它可以找到 2 个连接的未格式化物理驱动器并读取字节。该程序当前以管理员模式运行,因为我猜这是该程序可以看到未格式化硬盘的唯一方式。我正在使用 visual studio 2015,它在 Windows 7 机器上运行。

问题是它只能读取 512 的倍数(512 是扇区大小)。目前未格式化的硬盘位于磁盘 2 和 3 插槽(它们都是 SSD)。它首先读取 512 字节(可以正常工作),如果它是格式化的硬盘驱动器则不再读取。如果它是未格式化的硬盘驱动器,它会继续读取更多字节。如果它是硬盘驱动器 A,则它会读取接下来的 1024 个字节并且它可以工作(read_amount = 1024)。如果它是硬盘驱动器 B,则它会读取接下来的 1025 个字节,但它不起作用 (read_amount = 0)。我不确定为什么它不能读取 512/扇区大小的倍数。我的理解是,当您使用 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL 调用“CreateFile()”函数时,我应该能够读取不是扇区大小倍数的大小(如果您使用 FILE_FLAG_NO_BUFFERING,那么您只能读取 512 的倍数,而我没有使用那面旗帜)。请参阅下面的代码。

//Hard_Drive_Read.cpp : 定义控制台应用程序的入口点。

//该程序假设您有两个未格式化的硬盘驱动器连接到您的计算机。

#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <iomanip>


using namespace std;




int main(int argc, char *argv[])
{
if (argc != 3)
{
cout << "Need to enter 2 arguments" << endl;
exit(0);
}

int frames_to_process = atoi(argv[2]);

if (frames_to_process < 1)
{
cout << "invalid argument 2" << endl;
exit(0);
}



//HANDLE hDisk_A;
//HANDLE hDisk_B;



LPCTSTR dsksrc = L"\\\\.\\PhysicalDrive";
wchar_t dsk[512] = L"";


bool channel_A_found = false;
bool channel_B_found = false;
char frame_header_A[1024];
char frame_header_B[1025];



HANDLE hDisk;
char buff_read[512];
DWORD read_amount = 0;

for (int i = 0; i < 4; i++)
{


swprintf(dsk, 511, L"%s%d", dsksrc, i);

hDisk = CreateFile(dsk, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDisk == INVALID_HANDLE_VALUE)
{
printf("%s%d%s", "couldn't open the drive ", i, "\n");
CloseHandle(hDisk);
}
else
{
printf("%s%d%s", "successfully open the drive ", i, "\n");

BOOL read_success_1 = ReadFile(hDisk, buff_read, 512, &read_amount, NULL);
cout << "read amount 1 - " << read_amount << endl;
if ((read_success_1 == TRUE) && (read_amount == 512))
{


if ((buff_read[510] == (char)0x55) && (buff_read[511] == (char)0xAA)) // test for a formatted drive; is there other identifiers?
{
cout << i << " is a formatted drive" << endl;
}

else
{
cout << "Not a formatted drive, trying to find sync " << endl;


ofstream writeBinary_Test;

if (i == 2)
{
writeBinary_Test.open("file_A_test.bin", ofstream::out | ofstream::binary);
ReadFile(hDisk, frame_header_A, 1024, &read_amount, NULL);
cout << "read amount " << read_amount << endl;
writeBinary_Test.write(frame_header_A, 1024);
writeBinary_Test.close();
}

else if(i == 3)
{
writeBinary_Test.open("file_B_test.bin", ofstream::out | ofstream::binary);
ReadFile(hDisk, frame_header_B, 1025, &read_amount, NULL);
cout << "read amount " << read_amount << endl;
writeBinary_Test.write(frame_header_B, 1025);
writeBinary_Test.close();
}



LARGE_INTEGER distanceToMove;
SetFilePointerEx(hDisk, distanceToMove, NULL, FILE_BEGIN);



}
}

else
{

}

}

if (channel_A_found && channel_B_found)
{
cout << "both drives found" << endl;
break;
}
}


if ((channel_A_found == false) || (channel_B_found == false))
{
cout << "Couldn't Find Hard Drive A or Drive B or Both" << endl;
cout << "Exiting the program" << endl;
exit(0);
}


CloseHandle(hDisk);



return 0;
}

最后,我想使用 SetFilePointerEx() 在硬盘驱动器上移动,我的程序必须处理数据大小(不是 512 的倍数)。因此,我必须读取不是 512 倍数的大小。关于如何修复此程序的任何想法?我是否正确使用了我的标志?

非常感谢任何帮助!

最佳答案

documentation for CreateFile说:

Volume handles can be opened as noncached at the discretion of the particular file system, even when the noncached option is not specified in CreateFile. You should assume that all Microsoft file systems open volume handles as noncached. The restrictions on noncached I/O for files also apply to volumes.

虽然没有明确说明,但这适用于驱动器和卷。

实际上,这不是问题。编写一个从任意偏移量返回任意数量数据的辅助函数很简单,同时只执行对齐读取。

关于winapi - 从物理硬盘读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50842146/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com