c – Windows,打开原始磁盘

我正在尝试从原始磁盘读取字节. (Windows 7,VS 2010.)

我为hdisk得到一个值-1(我假设是一个错误).

我如何获得真实数据?

(这是我的第一个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;
}

解决方法:

我认为你的代码应该工作(当使用提升的权限运行时),除了:

> 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;
  }
}

相关文章

Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自...
主域控角色迁移和夺取(转载) 转载自:http://yupeizhi.blo...
Windows2012R2 NTP时间同步 Windows2012R2里没有了internet时...
Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...