从物理硬盘读取数据 [英] Reading Data from a Physical Hard Drive

查看:113
本文介绍了从物理硬盘读取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to develop a program that goes and finds 2 connected unformatted physical drives and read bytes. The program currently runs in the administrator mode since that's the only way I guess the program can see unformatted hard drives. I am using visual studio 2015 and it runs in windows 7 machine.

问题在于它只能读取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的倍数,而我没有使用该标志).请参阅下面的代码.

The problem is that it can only read multiples of 512 (512 is the sector size). Currently the unformatted hard drives are located in disk 2 and 3 slots (they are both SSDs). It first reads 512 bytes (works without an issue) and doesn't do any more reads if it's a formatted hard drive. If it's an unformatted hard drive it goes ahead and read more bytes. If it's hard drive A it then reads the next 1024 bytes and it works (read_amount = 1024). If it's hard drive B it then reads the next 1025 bytes and it doesn't work (read_amount = 0). I am not sure why it can't read a multiple of a 512/sector sizes. My understanding is that when you call "CreateFile()" function with dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, I should be able to read sizes that are not multiples of sector sizes (if you use FILE_FLAG_NO_BUFFERING then you can only read multiples of 512 and I am NOT using that flag). See my code below.

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

// Hard_Drive_Read.cpp : Defines the entry point for the console application.

//此程序假定计算机上确实有两个未格式化的硬盘驱动器.

// This program assumes you have EXACTLY TWO unformatted hard drives connected to your computer.

#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的倍数,这是当务之急.有关如何修复此程序的任何想法?我是否正确使用我的标志?

Eventually, I want to use SetFilePointerEx() to move around the hard drive and I the program has to work with and data size (not multiples of 512). Therefore, it's imperative I can read sizes that's not multiples of 512. Any ideas of how to fix this program? Am I using my flags properly?

非常感谢您的帮助!

推荐答案

即使未在CreateFile中指定noncached选项,也可以根据特定文件系统的判断,以非缓存的方式打开卷句柄.您应该假定所有Microsoft文件系统都将打开的卷句柄设置为未缓存.对文件的非缓存I/O的限制也适用于卷.

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.

尽管它没有明确说明,但它既适用于驱动器,也适用于卷.

Although it doesn't spell it out explicitly, this applies to drives as well as to volumes.

实际上,这不是问题.编写帮助函数可以直接从任意偏移返回任意数量的数据,而仅执行对齐的读取,很简单.

In practice, this isn't a problem. It is straightforward to write a helper function that returns an arbitrary amount of data from an arbitrary offset, while performing only aligned reads.

这篇关于从物理硬盘读取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆