SetFilePointerEx не в состоянии читать физический диск сверх размера LONG - PullRequest
1 голос
/ 18 января 2011

Прошло несколько лет, но я наконец-то погрузился в VC ++.Мне нужно иметь возможность прочитать x количество секторов физического устройства (а именно жесткого диска).Я использую API-интерфейсы CreateFile () и SetFilePointerEx () и ReadFile ().

  • Я много читал в Интернете на всех основных форумах по этой теме.Я исчерпал свои исследования, и теперь я чувствую, что пришло время попросить экспертов взвесить эту дилемму.Поскольку это мой самый первый пост в этой теме, пожалуйста, будьте осторожны с моей :)

  • Я должен также указать, что это .DLL, который я использую с простым приложением C #,Сантехника все работает отлично.Это API SetFilePointer (Ex) (), которые вызывают у меня горе.

Я могу заставить код работать до размера LONG (4, xxx, xxx) -Я не могу вспомнить точное значение.Достаточно сказать, что я могу читать все, вплоть до сектора # 4 000 000, но не 5 000 000 или выше.Проблема заключается в «размере» параметров для API-интерфейсов SetFilePointer () и SetFilePointerEx ().Я пробовал и то, и другое, SetFilePointerEx (), похоже, то, что я должен использовать для работы на 64-битных системах.

2-й и 3-й параметры SetFilePointer определены следующим образом:

BOOL WINAPI SetFilePointerEx(
  __in       HANDLE hFile,
  __in       LARGE_INTEGER liDistanceToMove,
  __out_opt  PLARGE_INTEGER lpNewFilePointer,
  __in       DWORD dwMoveMethod
);

Обратите внимание, что я попытался передать LowPart и HighPart в качестве 2-го и 3-го параметров без какого-либо успеха, так как я получаю CANNOT CONVERT LARGE_INTEGER TO PLARGE_INTEGER (для параметра 3).

ЗДЕСЬ МОЙКОД.Я ИСПОЛЬЗУЮ КОД-БРЕЙК ДЛЯ ПРОСМОТРА баффа [0] и т. Д. Я хотел бы прочитать за пределами ограничения 4, ххх, ххх.Очевидно, я делаю что-то не так.При каждом чтении, превышающем этот предел, указатель моего файла сбрасывается в сектор 0.

#include "stdafx.h"
#include <windows.h>
#include <conio.h>   



extern "C" 
  __declspec(dllexport)  int ReadSectors(long startSector, long numSectors)
 {

  HANDLE hFile;

  const int SECTOR_SIZE = 512;
  const int BUFFER_SIZE = 512;

  LARGE_INTEGER liDistanceToMove;  
  PLARGE_INTEGER newFilePtr = NULL;   // not used in this context.
                // just reading from START to END


  liDistanceToMove.QuadPart = startSector * SECTOR_SIZE;


  DWORD  dwBytesRead, dwPos;

  LPCWSTR fname = L"\\\\.\\PHYSICALDRIVE0";

  char buff[BUFFER_SIZE];


  // Open the PHYSICALDEVICE as a file. 
  hFile = CreateFile(fname,            
     GENERIC_READ | GENERIC_WRITE,             
     FILE_SHARE_READ | FILE_SHARE_WRITE,                       
     NULL,                      
     OPEN_EXISTING,            
     FILE_ATTRIBUTE_NORMAL,     
     NULL);                   


  // Here's the API definition

  /*BOOL WINAPI SetFilePointerEx(
    __in       HANDLE hFile,
    __in       LARGE_INTEGER liDistanceToMove,
    __out_opt  PLARGE_INTEGER lpNewFilePointer,
    __in       DWORD dwMoveMethod
  );*/


  dwPos = SetFilePointerEx(hFile, liDistanceToMove, NULL, FILE_BEGIN);


  if(ReadFile(hFile, buff, BUFFER_SIZE, &dwBytesRead, NULL))
  {
   if(dwBytesRead > 5)
   {

    BYTE x1 = buff[0];
    BYTE x2 = buff[1];
    BYTE x3 = buff[2];
    BYTE x4 = buff[3];
    BYTE x5 = buff[4];
   }

  }


  // Close both files.
  CloseHandle(hFile);


  return 0;
 }

1 Ответ

3 голосов
/ 18 января 2011
 startSector * SECTOR_SIZE;

startSector - это long (32 бита), SECTOR_SIZE - это int (также 32 бита), умножьте этих двух парней, и промежуточный результат будет длинным, который переполнится, и вы затем поместите его в 1004 * из LARGE_INTEGER, что слишком поздно. Вы хотите работать на __int64 s, что-то вроде

 liDistanceToMove.QuadPart = startSector;
 liDistanceToMove.QuadPart *= SECTOR_SIZE;

например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...