我正在尝试开发一个程序,找到2个连接的无格式物理驱动器和读取字节。该程序目前以管理员模式运行,因为这是我猜程序可以看到未格式化硬盘的唯一方法。我正在使用visual studio 2015,它在Windows 7机器上运行。
问题是它只能读取512的倍数(512是扇区大小)。目前,未格式化的硬盘驱动器位于磁盘2和3插槽中(它们都是SSD)。它首先读取512个字节(工作没有问题),如果它是格式化的硬盘驱动器,则不再执行任何读取操作。如果它是未格式化的硬盘驱动器,它会继续读取更多字节。如果它的硬盘驱动器A然后读取下一个1024字节并且它工作(read_amount = 1024)。如果它的硬盘驱动器B然后读取下一个1025字节并且它不起作用(read_amount = 0)。我不知道为什么它不能读取512 /扇区大小的倍数。我的理解是,当你打电话给" CreateFile()"函数与dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,我应该能够读取不是扇区大小倍数的大小(如果你使用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的倍数的大小。有关如何修复此程序的任何想法?我正确使用旗帜吗?
非常感谢任何帮助!
答案 0 :(得分:2)
documentation for CreateFile说:
即使未在CreateFile中指定非高速缓存选项,也可以根据特定文件系统的判断将卷句柄打开为非高速缓存。您应该假设所有Microsoft文件系统都将未处理的卷句柄打开。对文件的非高速缓存I / O的限制也适用于卷。
虽然它没有明确说明,但这适用于驱动器和卷。
在实践中,这不是问题。编写一个辅助函数是很简单的,该函数从任意偏移量返回任意数量的数据,同时只执行对齐的读取。
答案 1 :(得分:1)
我必须阅读的尺寸不是512的倍数。
这是不可能的。对于磁盘的直接访问,您只能读取和写入扇区大小的倍数。此外,您必须对齐读写操作。也就是说,文件指针必须是扇区大小的倍数。
如果您想提供一个允许任意搜索,读取和写入的界面,那么您需要在对齐的原始磁盘访问之上实现自己的缓冲。