2014-11-21 9 views
0

Я пытаюсь читать байты с необработанного диска. (Windows 7, VS 2010.)Windows, открывающий необработанный диск

Я получаю значение -1 для hDisk (что я предполагаю, это ошибка).

Как я могу получить реальные данные?

(Это моя программа первой Windows, C++, я обычно пишу для Linux.)

#include "stdafx.h" 
#include <windows.h> 
#include <WinIoCtl.h> 
#include <stdio.h> 
#include <iostream> 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    printf("hello world\n"); 
    DWORD nRead; 
    char buf[512]; 

    HANDLE hDisk = CreateFile(L"\\\\.\\PhysicalDrive0", 
     GENERIC_READ, FILE_SHARE_READ,   
     NULL, OPEN_EXISTING, 0, NULL); 

    printf("hDisk %i\n", hDisk); 

    SetFilePointer(hDisk, 0xA00, 0, FILE_BEGIN); 
    ReadFile(hDisk, buf, 512, &nRead, NULL); 
    for (int currentpos=0;currentpos < 512;currentpos++) { 
     std::cout << buf[currentpos]; 
    } 
    CloseHandle(hDisk); 
    std::cin.get(); 

    return 0; 
} 
+1

Вы пытались позвонить GetLastError? Что он вернулся? Я подозреваю, что вы не сможете этого сделать, если у вас нет прав администратора. – RobH

+1

Использование '% i' для печати' HANDLE' является неопределенным поведением. [Документация] (http://msdn.microsoft.com/en-ca/library/windows/desktop/aa383751 (v = vs.85).aspx) говорит, что это 'void *', что означает, что '% p' будет работать. Или вы можете просто использовать 'std :: cout'. Вы также не должны ничего принимать о значении. В соответствии с документацией для «CreateFile» вы можете сравнить ее с «INVALID_HANDLE_VALUE» и вызвать «GetLastError» для получения дополнительной информации, если они равны. – chris

+0

Вопрос: что вы хотите сделать? Записать драйвер устройства или установить определенный том? – Ajay

ответ

2

Ваш код должен я думаю, что работа (при запуске с повышенными привилегиями), за исключением:

  • buf[] не выровнена.

  • Физический диск 0, вероятно, будет системным приводом и, следовательно, используется.

Вот код, который я использую для создания образов дисков. (Previously posted here.) Общественное достояние, но без каких-либо гарантий, явных или подразумеваемых и т. Д. (Оглядываясь на код, я отмечаю, что я явно не проверял размер сектора, чтобы убедиться, что операции буфера и чтения/записи правильно выровнены. Это не должно быть проблемой на практике, потому что наибольший размер сектора в общем использовании составляет 4K, а это также размер страницы памяти в Windows. Однако в производственном коде вы всегда должны явно определять размер сектора рассматриваемого устройства и обеспечить надлежащее выравнивание соответственно.)

#define _WIN32_WINNT 0x0501 

#include <windows.h> 

#include <stdio.h> 

#define dump_buffersize_megs 16 
#define dump_buffersize (dump_buffersize_megs * 1024 * 1024) 
#define dump_workingsetsize ((dump_buffersize_megs + 1) * 1024 * 1024) 

DWORD save(const wchar_t * source_device_name, const wchar_t * filename) { 

    DWORD err; 

    HANDLE hdevice, houtput; 

    DWORD bytes_to_transfer, byte_count; 

    GET_LENGTH_INFORMATION source_disklength; 

    DISK_GEOMETRY source_diskgeometry; 

    LARGE_INTEGER offset; 

    OVERLAPPED overlapped; 

    BYTE * buffer; 

    if (!SetProcessWorkingSetSize(GetCurrentProcess(), dump_workingsetsize, dump_workingsetsize)) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to expand working set.\n", err); 
    return err; 
    } 

    buffer = VirtualAlloc(NULL, dump_buffersize, MEM_COMMIT, PAGE_READWRITE); 

    if (buffer == NULL) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to allocate buffer.\n", err); 
    return err; 
    } 

    if (!VirtualLock(buffer, dump_buffersize)) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to lock buffer.\n", err); 
    return err; 
    } 

    hdevice = CreateFile 
    (
    source_device_name, 
    GENERIC_READ, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_NO_BUFFERING, 
    NULL 
    ); 

    if (hdevice == INVALID_HANDLE_VALUE) { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u opening input device.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    hdevice, 
    FSCTL_LOCK_VOLUME, 
    NULL, 
    0, 
    NULL, 
    0, 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u locking input volume.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    hdevice, 
    IOCTL_DISK_GET_DRIVE_GEOMETRY, 
    NULL, 
    0, 
    &source_diskgeometry, 
    sizeof(source_diskgeometry), 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u getting device geometry.\n", err); 
    return err; 
    } 

    switch (source_diskgeometry.MediaType) 
    { 
    case Unknown: 
    case RemovableMedia: 
    case FixedMedia: 

    if (!DeviceIoControl 
     (
     hdevice, 
     IOCTL_DISK_GET_LENGTH_INFO, 
     NULL, 
     0, 
     &source_disklength, 
     sizeof(source_disklength), 
     &byte_count, 
     NULL 
    )) 
    { 
     err = GetLastError(); 
     fprintf(stderr, "Error %u getting input device length.\n", err); 
     return err; 
    } 

    fprintf(stderr, "\nInput disk has %I64i bytes.\n\n", source_disklength.Length.QuadPart); 
    break; 

    default: 

    source_disklength.Length.QuadPart = 
     source_diskgeometry.Cylinders.QuadPart * 
     source_diskgeometry.TracksPerCylinder * 
     source_diskgeometry.SectorsPerTrack * 
     source_diskgeometry.BytesPerSector; 

    fprintf(stderr, 
     "\n" 
     "Input device appears to be a floppy disk. WARNING: if this is not a\n" 
     "floppy disk the calculated size will probably be incorrect, resulting\n" 
     "in an incomplete copy.\n" 
     "\n" 
     "Input disk has %I64i bytes.\n" 
     "\n", 
     source_disklength.Length.QuadPart); 

    break; 
    } 

    houtput = CreateFile 
    (
    filename, 
    GENERIC_WRITE, 
    0, 
    NULL, 
    CREATE_ALWAYS, 
    FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, 
    NULL 
    ); 

    if (houtput == INVALID_HANDLE_VALUE) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u creating output file.\n", err); 
    return err; 
    } 

    offset.QuadPart = 0; 
    overlapped.hEvent = 0; 

    for (;;) 
    { 
    overlapped.Offset = offset.LowPart; 
    overlapped.OffsetHigh = offset.HighPart; 

    if (source_disklength.Length.QuadPart - offset.QuadPart < dump_buffersize) 
    { 
     bytes_to_transfer = (DWORD)(source_disklength.Length.QuadPart - offset.QuadPart); 
     if (bytes_to_transfer == 0) break; 
    } 
    else 
    { 
     bytes_to_transfer = dump_buffersize; 
    } 

    if (!ReadFile(hdevice, buffer, bytes_to_transfer, NULL, &overlapped)) 
    { 
     err = GetLastError(); 
     printf("Error %u initiating read from input disk.\n", err); 
     return err; 
    } 

    if (!GetOverlappedResult(hdevice, &overlapped, &byte_count, TRUE)) 
    { 
     err = GetLastError(); 
     printf("Error %u reading from input disk.\n", err); 
     return err; 
    } 

    if (byte_count != bytes_to_transfer) 
    { 
     err = GetLastError(); 
     printf("Internal error - partial read. Last error code %u.\n", err); 
     printf("bytes_to_transfer = %u; byte_count = %u.\n", bytes_to_transfer, byte_count); 
     if (byte_count == 0) return ERROR_INVALID_FUNCTION; 
     bytes_to_transfer = byte_count; 
    } 

    if (!WriteFile(houtput, buffer, bytes_to_transfer, NULL, &overlapped)) 
    { 
     err = GetLastError(); 
     if (err != ERROR_IO_PENDING) 
     { 
     printf("Error %u initiating write to output file.\n", err); 
     return err; 
     } 
    } 

    if (!GetOverlappedResult(houtput, &overlapped, &byte_count, TRUE)) 
    { 
     err = GetLastError(); 
     printf("Error %u writing to output file.\n", err); 
     return err; 
    } 

    if (byte_count != bytes_to_transfer) 
    { 
     printf("Internal error - partial write.\n"); 
     printf("bytes_to_transfer = %u; byte_count = %u.\n", bytes_to_transfer, byte_count); 
     return ERROR_INVALID_FUNCTION; 
    } 

    offset.QuadPart += bytes_to_transfer; 
    } 

    overlapped.Offset = offset.LowPart; 
    overlapped.OffsetHigh = offset.HighPart; 

    if (!ReadFile(hdevice, buffer, source_diskgeometry.BytesPerSector, NULL, &overlapped)) 
    { 
    err = GetLastError(); 
    if (err == ERROR_HANDLE_EOF) 
    { 
     printf("Save successfully completed.\n");  
     return 0; 
    } 
    printf("Error %u initiating read from input disk past end of file.\n", err); 
    return err; 
    } 

    if (!GetOverlappedResult(hdevice, &overlapped, &byte_count, TRUE)) 
    { 
    err = GetLastError(); 
    if (err == ERROR_HANDLE_EOF) 
    { 
     printf("Save successfully completed.\n");  
     return 0; 
    } 
    printf("Error %u reading from input disk past end of file.\n", err); 
    return err; 
    } 

    if (byte_count == 0) 
    { 
    printf("Save successfully completed.\n"); 
    return 0; 
    } 

    printf("WARNING: the expected amount of data was successfully copied,\n" 
     "but end of file not detected on input disk. The copy might\n" 
     "not be complete."); 

    return ERROR_MORE_DATA; 

} 

DWORD write(const wchar_t * filename, const wchar_t * target_device_name) { 

    DWORD err; 

    HANDLE hinput, houtput; 

    WIN32_FILE_ATTRIBUTE_DATA fad; 

    DWORD bytes_to_transfer, byte_count; 

    LARGE_INTEGER filelength; 

    GET_LENGTH_INFORMATION target_disklength; 

    DISK_GEOMETRY target_diskgeometry; 

    LARGE_INTEGER transfer_length; 

    LARGE_INTEGER offset; 

    OVERLAPPED overlapped; 

    BYTE * buffer; 

    if (!SetProcessWorkingSetSize(GetCurrentProcess(), dump_workingsetsize, dump_workingsetsize)) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to expand working set.\n", err); 
    return err; 
    } 

    buffer = VirtualAlloc(NULL, dump_buffersize, MEM_COMMIT, PAGE_READWRITE); 

    if (buffer == NULL) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to allocate buffer.\n", err); 
    return err; 
    } 

    if (!VirtualLock(buffer, dump_buffersize)) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to lock buffer.\n", err); 
    return err; 
    } 

    if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad)) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u reading input file attributes.\n", err); 
    return err; 
    } 

    filelength.HighPart = fad.nFileSizeHigh; 
    filelength.LowPart = fad.nFileSizeLow; 

    fprintf(stderr, "\nInput file has %I64i bytes.\n", filelength.QuadPart); 

    hinput = CreateFile 
    (
    filename, 
    GENERIC_READ, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, 
    NULL 
    ); 

    if (hinput == INVALID_HANDLE_VALUE) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u opening input file.\n", err); 
    return err; 
    } 

    houtput = CreateFile 
    (
    target_device_name, 
    GENERIC_READ | GENERIC_WRITE, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_NO_BUFFERING, 
    NULL 
    ); 

    if (houtput == INVALID_HANDLE_VALUE) { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u opening output device.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    houtput, 
    FSCTL_LOCK_VOLUME, 
    NULL, 
    0, 
    NULL, 
    0, 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u locking volume.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    houtput, 
    IOCTL_DISK_GET_DRIVE_GEOMETRY, 
    NULL, 
    0, 
    &target_diskgeometry, 
    sizeof(target_diskgeometry), 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u getting output device geometry.\n", err); 
    return err; 
    } 

    switch (target_diskgeometry.MediaType) 
    { 
    case Unknown: 
    case RemovableMedia: 
    case FixedMedia: 

    if (!DeviceIoControl 
     (
     houtput, 
     IOCTL_DISK_GET_LENGTH_INFO, 
     NULL, 
     0, 
     &target_disklength, 
     sizeof(target_disklength), 
     &byte_count, 
     NULL 
    )) 
    { 
     err = GetLastError(); 
     fprintf(stderr, "Error %u getting output device length.\n", err); 
     return err; 
    } 

    fprintf(stderr, "Output disk has %I64i bytes.\n\n", target_disklength.Length.QuadPart); 
    break; 

    default: 

    target_disklength.Length.QuadPart = 
     target_diskgeometry.Cylinders.QuadPart * 
     target_diskgeometry.TracksPerCylinder * 
     target_diskgeometry.SectorsPerTrack * 
     target_diskgeometry.BytesPerSector; 

    fprintf(stderr, 
     "\n" 
     "Output device appears to be a floppy disk. WARNING: if this is not a\n" 
     "floppy disk the calculated output device size is probably incorrect,\n" 
     "which might result in an incomplete copy.\n" 
     "\n" 
     "Output disk has %I64i bytes.\n" 
     "\n", 
     target_disklength.Length.QuadPart); 

    break; 
    } 

    if (filelength.QuadPart == target_disklength.Length.QuadPart) 
    { 
    transfer_length.QuadPart = filelength.QuadPart; 
    } 
    else if (filelength.QuadPart < target_disklength.Length.QuadPart) 
    { 
    fprintf(stderr, "Image is smaller than target. Part of the target will not be written to.\n\n"); 
    transfer_length.QuadPart = filelength.QuadPart; 
    } 
    else 
    { 
    fprintf(stderr, "Image is larger than target. Part of the image will not be copied.\n\n"); 
    transfer_length.QuadPart = target_disklength.Length.QuadPart; 
    } 

    offset.QuadPart = 0; 
    overlapped.hEvent = 0; 

    for (;;) 
    { 
    overlapped.Offset = offset.LowPart; 
    overlapped.OffsetHigh = offset.HighPart; 

    if (transfer_length.QuadPart - offset.QuadPart < dump_buffersize) 
    { 
     bytes_to_transfer = (DWORD)(transfer_length.QuadPart - offset.QuadPart); 
     if (bytes_to_transfer == 0) break; 
    } 
    else 
    { 
     bytes_to_transfer = dump_buffersize; 
    } 

    if (!ReadFile(hinput, buffer, bytes_to_transfer, NULL, &overlapped)) 
    { 
     err = GetLastError(); 
     if (err != ERROR_IO_PENDING) 
     { 
     printf("Error %u initiating read from input file.\n", err); 
     return err; 
     } 
    } 

    if (!GetOverlappedResult(hinput, &overlapped, &byte_count, TRUE)) 
    { 
     err = GetLastError(); 
     printf("Error %u reading from input file.\n", err); 
     return err; 
    } 

    if (byte_count != bytes_to_transfer) 
    { 
     err = GetLastError(); 
     printf("Internal error - partial read. Last error code %u.\n", err); 
     printf("bytes_to_transfer = %u; byte_count = %u.\n", bytes_to_transfer, byte_count); 
     if (byte_count == 0) return ERROR_INVALID_FUNCTION; 
     bytes_to_transfer = byte_count; 
    } 

    if (!WriteFile(houtput, buffer, bytes_to_transfer, NULL, &overlapped)) 
    { 
     err = GetLastError(); 
     if (err != ERROR_IO_PENDING) 
     { 
     printf("Error %u initiating write to output disk.\n", err); 
     return err; 
     } 
    } 

    if (!GetOverlappedResult(houtput, &overlapped, &byte_count, TRUE)) 
    { 
     err = GetLastError(); 
     printf("Error %u writing to output disk.\n", err); 
     return err; 
    } 

    if (byte_count != bytes_to_transfer) 
    { 
     printf("Internal error - partial write.\n"); 
     printf("bytes_to_transfer = %u; byte_count = %u.\n", bytes_to_transfer, byte_count); 
     return ERROR_INVALID_FUNCTION; 
    } 

    offset.QuadPart += bytes_to_transfer; 
    } 

    printf("Write successfully completed.\n"); 
    return 0; 
} 

DWORD clone(const wchar_t * source_device_name, const wchar_t * target_device_name) { 

    DWORD err; 

    HANDLE hinput, houtput; 

    DWORD bytes_to_transfer, byte_count; 

    GET_LENGTH_INFORMATION source_disklength; 

    DISK_GEOMETRY source_diskgeometry; 

    GET_LENGTH_INFORMATION target_disklength; 

    DISK_GEOMETRY target_diskgeometry; 

    LARGE_INTEGER transfer_length; 

    LARGE_INTEGER offset; 

    OVERLAPPED overlapped; 

    BYTE * buffer; 

    DWORD result; 

    if (!SetProcessWorkingSetSize(GetCurrentProcess(), dump_workingsetsize, dump_workingsetsize)) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to expand working set.\n", err); 
    return err; 
    } 

    buffer = VirtualAlloc(NULL, dump_buffersize, MEM_COMMIT, PAGE_READWRITE); 

    if (buffer == NULL) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to allocate buffer.\n", err); 
    return err; 
    } 

    if (!VirtualLock(buffer, dump_buffersize)) 
    { 
    err = GetLastError(); 
    printf("Error %u trying to lock buffer.\n", err); 
    return err; 
    } 

    hinput = CreateFile 
    (
    source_device_name, 
    GENERIC_READ, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_NO_BUFFERING, 
    NULL 
    ); 

    if (hinput == INVALID_HANDLE_VALUE) { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u opening input device.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    hinput, 
    FSCTL_LOCK_VOLUME, 
    NULL, 
    0, 
    NULL, 
    0, 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u locking input volume.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    hinput, 
    IOCTL_DISK_GET_DRIVE_GEOMETRY, 
    NULL, 
    0, 
    &source_diskgeometry, 
    sizeof(source_diskgeometry), 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u getting device geometry.\n", err); 
    return err; 
    } 

    switch (source_diskgeometry.MediaType) 
    { 
    case Unknown: 
    case RemovableMedia: 
    case FixedMedia: 

    if (!DeviceIoControl 
     (
     hinput, 
     IOCTL_DISK_GET_LENGTH_INFO, 
     NULL, 
     0, 
     &source_disklength, 
     sizeof(source_disklength), 
     &byte_count, 
     NULL 
    )) 
    { 
     err = GetLastError(); 
     fprintf(stderr, "Error %u getting input device length.\n", err); 
     return err; 
    } 

    fprintf(stderr, "\nInput disk has %I64i bytes.\n", source_disklength.Length.QuadPart); 
    break; 

    default: 

    source_disklength.Length.QuadPart = 
     source_diskgeometry.Cylinders.QuadPart * 
     source_diskgeometry.TracksPerCylinder * 
     source_diskgeometry.SectorsPerTrack * 
     source_diskgeometry.BytesPerSector; 

    fprintf(stderr, 
     "\n" 
     "Input device appears to be a floppy disk. WARNING: if this is not a\n" 
     "floppy disk the calculated disk size is probably incorrect, resulting\n" 
     "in an incomplete copy.\n" 
     "\n" 
     "Input disk has %I64i bytes.\n", 
     source_disklength.Length.QuadPart); 

    break; 
    } 

    houtput = CreateFile 
    (
    target_device_name, 
    GENERIC_READ | GENERIC_WRITE, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_NO_BUFFERING, 
    NULL 
    ); 

    if (houtput == INVALID_HANDLE_VALUE) { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u opening output device.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    houtput, 
    FSCTL_LOCK_VOLUME, 
    NULL, 
    0, 
    NULL, 
    0, 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u locking output volume.\n", err); 
    return err; 
    } 

    if (!DeviceIoControl 
    (
    houtput, 
    IOCTL_DISK_GET_DRIVE_GEOMETRY, 
    NULL, 
    0, 
    &target_diskgeometry, 
    sizeof(target_diskgeometry), 
    &byte_count, 
    NULL 
    )) 
    { 
    err = GetLastError(); 
    fprintf(stderr, "Error %u getting output device geometry.\n", err); 
    return err; 
    } 

    switch (target_diskgeometry.MediaType) 
    { 
    case Unknown: 
    case RemovableMedia: 
    case FixedMedia: 

    if (!DeviceIoControl 
     (
     houtput, 
     IOCTL_DISK_GET_LENGTH_INFO, 
     NULL, 
     0, 
     &target_disklength, 
     sizeof(target_disklength), 
     &byte_count, 
     NULL 
    )) 
    { 
     err = GetLastError(); 
     fprintf(stderr, "Error %u getting output device length.\n", err); 
     return err; 
    } 

    fprintf(stderr, "Output disk has %I64i bytes.\n\n", target_disklength.Length.QuadPart); 
    break; 

    default: 

    target_disklength.Length.QuadPart = 
     target_diskgeometry.Cylinders.QuadPart * 
     target_diskgeometry.TracksPerCylinder * 
     target_diskgeometry.SectorsPerTrack * 
     target_diskgeometry.BytesPerSector; 

    fprintf(stderr, 
     "\n" 
     "Output device appears to be a floppy disk. WARNING: if this is not a\n" 
     "floppy disk the calculated output device size is probably incorrect,\n" 
     "which might result in an incomplete copy.\n" 
     "\n" 
     "Output disk has %I64i bytes.\n" 
     "\n", 
     target_disklength.Length.QuadPart); 

    break; 
    } 

    if (source_disklength.Length.QuadPart == target_disklength.Length.QuadPart) 
    { 
    transfer_length.QuadPart = source_disklength.Length.QuadPart; 
    } 
    else if (source_disklength.Length.QuadPart < target_disklength.Length.QuadPart) 
    { 
    printf("Input shorter than output. Part of the output disk will not be written to.\n\n"); 
    transfer_length.QuadPart = source_disklength.Length.QuadPart; 
    } 
    else 
    { 
    printf("Output shorter than input. Copy will be truncated to output length.\n\n"); 
    transfer_length.QuadPart = target_disklength.Length.QuadPart; 
    } 

    offset.QuadPart = 0; 
    overlapped.hEvent = 0; 

    for (;;) 
    { 
    overlapped.Offset = offset.LowPart; 
    overlapped.OffsetHigh = offset.HighPart; 

    if (transfer_length.QuadPart - offset.QuadPart < dump_buffersize) 
    { 
     bytes_to_transfer = (DWORD)(transfer_length.QuadPart - offset.QuadPart); 
     if (bytes_to_transfer == 0) break; 
    } 
    else 
    { 
     bytes_to_transfer = dump_buffersize; 
    } 

    if (!ReadFile(hinput, buffer, bytes_to_transfer, NULL, &overlapped)) 
    { 
     err = GetLastError(); 
     printf("Error %u initiating read from input file.\n", err); 
     return err; 
    } 

    if (!GetOverlappedResult(hinput, &overlapped, &byte_count, TRUE)) 
    { 
     err = GetLastError(); 
     printf("Error %u reading from input file.\n", err); 
     return err; 
    } 

    if (byte_count != bytes_to_transfer) 
    { 
     err = GetLastError(); 
     printf("Internal error - partial read. Last error code %u.\n", err); 
     printf("bytes_to_transfer = %u; byte_count = %u.\n", bytes_to_transfer, byte_count); 
     if (byte_count == 0) return ERROR_INVALID_FUNCTION; 
     bytes_to_transfer = byte_count; 
    } 

    if (!WriteFile(houtput, buffer, bytes_to_transfer, NULL, &overlapped)) 
    { 
     err = GetLastError(); 
     if (err != ERROR_IO_PENDING) 
     { 
     printf("Error %u initiating write to output disk.\n", err); 
     return err; 
     } 
    } 

    if (!GetOverlappedResult(houtput, &overlapped, &byte_count, TRUE)) 
    { 
     err = GetLastError(); 
     printf("Error %u writing to output disk.\n", err); 
     return err; 
    } 

    if (byte_count != bytes_to_transfer) 
    { 
     printf("Internal error - partial write.\n"); 
     printf("bytes_to_transfer = %u; byte_count = %u.\n", bytes_to_transfer, byte_count); 
     return ERROR_INVALID_FUNCTION; 
    } 

    offset.QuadPart += bytes_to_transfer; 
    } 

    if (transfer_length.QuadPart == source_disklength.Length.QuadPart) 
    { 
    overlapped.Offset = offset.LowPart; 
    overlapped.OffsetHigh = offset.HighPart; 

    if (!ReadFile(hinput, buffer, source_diskgeometry.BytesPerSector, NULL, &overlapped)) 
    { 
     err = GetLastError(); 
     if (err == ERROR_HANDLE_EOF) 
     { 
     printf("Copy successfully completed.\n");  
     return 0; 
     } 
     printf("Error %u initiating read from input disk past end of file.\n", err); 
     return err; 
    } 

    if (!GetOverlappedResult(hinput, &overlapped, &byte_count, TRUE)) 
    { 
     err = GetLastError(); 
     if (err == ERROR_HANDLE_EOF) 
     { 
     printf("Copy successfully completed.\n"); 
     return 0; 
     } 
     printf("Error %u reading from input disk past end of file.\n", err); 
     return err; 
    } 

    if (byte_count == 0) 
    { 
     printf("Copy successfully completed.\n"); 
     return 0; 
    } 

    printf("WARNING: the expected amount of data was successfully copied,\n" 
      "but end of file not detected on input disk. The copy might\n" 
      "not be complete."); 

    result = ERROR_MORE_DATA; 
    return 0; 
    } 

    printf("Copy successfully completed.\n"); 
    return 0; 
} 

int wmain(int argc, wchar_t ** argv) 
{ 
    if (argc < 4) 
    { 
    printf("Syntax: \n" 
     "To save an image of a physical drive:\n" 
     "diskimage /save \\\\.\\PhysicalDrive0 file.img\n" 
     "diskimage /save \\\\.\\A: file.img\n" 
     "To write from an image file to a physical drive:\n" 
     "diskimage /write file.img \\\\.\\PhysicalDrive0\n" 
     "diskimage /write file.img \\\\.\\A:\n" 
     "To clone input drive 0 to output drive 1:\n" 
     "diskimage /clone \\\\.\\PhysicalDrive0 \\\\.\\PhysicalDrive1\n" 
    ); 
    return 1; 
    } 
    if (_wcsicmp(argv[1], L"/save") == 0) 
    { 
    return save(argv[2], argv[3]); 
    } 
    else if (_wcsicmp(argv[1], L"/write") == 0) 
    { 
    return write(argv[2], argv[3]); 
    } 
    else if (_wcsicmp(argv[1], L"/clone") == 0) 
    { 
    return clone(argv[2], argv[3]); 
    } 
    else 
    { 
    printf("Invalid argument. Use /? for syntax help.\n"); 
    return 1; 
    } 
} 
2

Документация CreateFile ясно говорит:

Физические диски и тома

Прямой доступ к диску или к тому ограничен. Для получения дополнительной информации о см. «Изменения в файловой системе и стеке хранилища , чтобы ограничить прямой доступ к диску и прямой доступ к тому в Windows Vista и Windows Server 2008» в справочном и вспомогательном знании База на http://support.microsoft.com/kb/942448.

IMO, нет необходимости напрямую обращаться к содержимому физического диска, если только вы не пишете драйвер устройства.

EDIT:

Чтобы добавить некоторую информацию для начинающего разработчика ОС Windows: Вам нужно запустить программу повышенной, даже если вы вошли в систему с правами администратора. UAC контролирует это. Вы можете сделать вашу программу всегда запускать приподнятоLinker-> Файл манифеста-> Уровень выполнения UAC и установите его в requireAdministrator. Это необходимо для любой задачи с правами администратора, так же просто, как SetSystemTime.

+0

Спасибо за подсказку requireAdministrator. – fadedbee

+1

Имеются допустимые варианты использования, не связанные с драйверами устройств, в том числе изображения или клонирование дисков, восстановление удаленных разделов и т. Д. –

+0

@HarryJohnston Может ли разработчик написать версию «dd», которая работает на 64-битной Windows 7+? Требуется ли подписание кода? Является ли стоимость/процесс подписания исключительно корпоративными? (P.S. Я знаю о http://www.chrysocome.net/dd, но он говорит о WinXP/2k.) – fadedbee