2011-01-17 13 views
1

これは数年ですが、最終的にはVC++に突入しています。私は、物理デバイス(すなわち、ハードドライブ)のx個のセクタを読み取ることができる必要があります。私はCreateFile()とSetFilePointerEx()とReadFile()APIを使用しています。SetFilePointerExがLONGのサイズを超える物理ディスクを読み取れません

  • 私はこのトピックに関するすべての主要なフォーラムでオンラインで多くの読書を行っています。私は自分の研究を疲れさせてしまったので、専門家にこのジレンマを勘案してもらう時間だと思っています。これはこれまで私の最初の記事ですので、このトピックでは簡単に行ってください:)

  • これは私が単純なC#アプリケーションで消費する.DLLであることを指摘しておきます。配管はすべて正常に動作します。それは私の悲しみを引き起こしているSetFilePointer(Ex)()APIです。

私は、LONG(4、xxx、xxx)のサイズまで作業するコードを得ることができます。正確な値を覚えていません。セクター#4,000,000までは読めるが、5,000,000以上ではないすべてを読むことができれば十分である。問題は、SetFilePointer()およびSetFilePointerEx()APIのパラメータの「サイズ」にあります。私はこれまでに両方を試しましたが、SetFilePointerEx()は64ビットシステムで動作するために使用する必要があります。

次のようにSetFilePointerの2番目と3番目のパラメータが定義されています。

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

は私がすることはできません取得するよう、私は任意の成功なしで2番目と3つのパラメータとしてLowPartとHighPartを渡して試してみましたのでご注意くださいLARGE_INTEGERからPLARGE_INTEGER(パラメータ3の場合)に変換します。

ここにはマイコードがあります。私はbuff-0を見るためにコードブレークを使います。私は4、xxx、xxxの制限を過ぎて読んでいます。明らかに私は何か間違っている。それぞれがこの制限を超えて読みstartSectorはlong(32ビット)である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; 
} 

答えて

3
startSector * SECTOR_SIZE; 

部門に私のファイルポインタをリセットし、SECTOR_SIZEはint(も32ビット)で、これらの2人の男を乗算し、中間結果が起こっていますオーバーフローする長さにすると、それは遅すぎるの LARGE_INTEGERのそれに詰め込む。例えば、

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

のようなもので__int64秒で操作したいとします。

+0

えええええええええええええと、それは非常に面白くて、今あなたが指摘しています。 LARGE_INTEGER(内部的には、LowPartとHighPartを作成しています)のstructの考え方は、少し新しくなっています。私はQuadPart自体で動作するとは考えていませんでした。私はこれを試すことを楽しみにしています。どうもありがとう! –