2011-12-04 5 views
-1

私はFileRead APIを使用しています。 私はWindows 7 x64を使用していて、私のコードは正常に動作しています。 新しいWindows 7 x86およびVS2008チームワークと.NET 2、3 + SP1 + SP2、3.5、3.5.1をインストールしました。 私は管理者としての私のコードを実行しますが、それでもfollwoingエラーが発生します。FileRead APIを使用している場合のAccessViolationException

AccessViolationException(Attempted to read or write protected memory. This is often an indication that other memory is corrupt.)

int nread = 0; 
uint handle; 
byte[] buff = new byte[1024]; 
string driveRoot = string.Concat("\\\\.\\", driveLetter); 
uint hRoot = CreateFile(driveRoot, 
       GENERIC_READ | GENERIC_WRITE, 
       FILE_SHARE_READ | FILE_SHARE_WRITE, 
       IntPtr.Zero, 
       OPEN_EXISTING, 
       FILE_ATTRIBUTE_NORMAL, 
       IntPtr.Zero); 
if (hRoot != -1) 
     handle = ReadFile(hRoot, buff, 1024, nread, new System.Threading.NativeOverlapped()); 
+1

あなたのハンドルがのIntPtrでなければなりませんが、それは、x86上の問題になることはありません。しかし、x64でも問題になっていたはずです。そしてnreadもポインタとして渡され、あなたはuintを渡しています。 IntPtrでなければなりません。 –

答えて

1

私はC#の第一人者だありませんが、あなたが間違ったパラメータでReadFile()を起動しているように私には見えます。

第4パラメータは、読み取られたバイト数を受け取る整数へのポインタでなければなりません。整数(nread)を指定し、そのアドレス(&nread)は指定しません。

そして、あなたは非同期のファイルI/Oを使用する場合に限り、ReadFile()の最後のパラメータはNULLポインタ(または単に0)でなければなりません。

this example on MSDNを参照してください。

+0

しかし、Windows7 x64で正しく動作します! Windows7 x86で同じコードが正しく動作しないのはなぜですか? 何が問題なのですか? –

+0

win32はポインタを期待し、ゼロのintを渡すとNULLポインタに等しいので、おそらくnreadが機能します。 –

+0

重複した読み込みが問題になると思います。あなたは間違いなくここで重複したくありません。その結果、バッファの割り当てが解除された後に、バッファへの書き込みが長くなる可能性があります。 –

0

私はあなたのコードの主な問題は、あなたが重複したI/Oを要求するが、ときReadFileリターン存在しなくなったバッファを供給していることであると思われます。これは、システムが非同期に操作を実行するかどうかを決定し、あるシステムで非同期を実行せず、別のシステムで非同期を選択しないことを選択できるため、一部のシステムでのみ動作します。

I/Oが重複しないように、NULLを最後のパラメータReadFileに渡すだけです。一方

は、おそらくあなたのコードは、すべてのx64システム上で動作していないとAV限り取得することはありません。あなたのハンドルタイプは32ビット整数として誤って宣言されています。

あなたのコードには他にも小さな問題がたくさんあります。これらのエラーを修正するコードの編集バージョンです。 P/invokeシグネチャはpinvoke.netから取得されました。

  • ハンドルを格納するための32ビット整数を誤って使用する:あなたのコード内のエラーを要約する

    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern IntPtr CreateFile(
        string lpFileName, 
        uint dwDesiredAccess, 
        uint dwShareMode, 
        IntPtr SecurityAttributes, 
        uint dwCreationDisposition, 
        uint dwFlagsAndAttributes, 
        IntPtr hTemplateFile 
    ); 
    
    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool ReadFile(
        IntPtr hFile, 
        [Out] byte[] lpBuffer, 
        uint nNumberOfBytesToRead, 
        out uint lpNumberOfBytesRead, 
        IntPtr lpOverlapped 
    ); 
    
    static void Main(string[] args) 
    { 
        string physicalDrive = @"\\.\PhysicalDrive0"; 
        IntPtr hFile = CreateFile(
         physicalDrive, 
         GENERIC_READ | GENERIC_WRITE, 
         FILE_SHARE_READ | FILE_SHARE_WRITE, 
         IntPtr.Zero, 
         OPEN_EXISTING, 
         FILE_ATTRIBUTE_NORMAL, 
         IntPtr.Zero 
        ); 
        if (hFile.ToInt64() != INVALID_HANDLE_VALUE) 
        { 
         byte[] buff = new byte[1024]; 
         uint nread; 
         if (ReadFile(hFile, buff, (uint)buff.Length, out nread, IntPtr.Zero)) 
          Console.WriteLine("Read successful"); 
        } 
    } 
    

  • P/invoke宣言がReadFileの場合、lpNumberOfBytesReadが正しく宣言されていません。
  • ReadFileハンドルを返さない場合は、関数呼び出しの成功を示すブール値を返します。
  • 不要なオーバーラップI/Oを使用し、マーシャリングされたbyte[]バッファでは動作しません。
  • GetLastErrorを管理コードから呼び出すことは決してありません(これはコメントに表示されたコードで行いました)。代わりにMarshal.GetLastWin32Errorに電話してください。その理由は、その方法のdocumentationで説明されています。
+0

tnx for edit.now私はSetFilePointerEx.iでhfileからオフセットに移動しましたが、これは正しく実行されませんでした==> SetFilePointerEx(hRoot、MFTAddress、ref newaddress、0); intエラー= GetLastError(); if(hRoot!= IntPtr.Zero) handle = ReadFile(hRoot、buff、1024、ref nread、new System.Threading.NativeOverlapped());

+0

@Saeed私はあなたの元の質問に答えたと思います。今あなたはあなたのコメントで別の質問をしているようです。あなたはどのように失敗したのかは言わなかった。 「それは正しく機能しません」とは、私たちがあなたを助けるのに十分な情報ではありません。さらに、コメントでコードを提供することは、読みやすい方法でフォーマットされていないため、役に立たない。質問は編集でき、新しい質問をすることができます。記録のために、私の答えは元の問題を解決しましたか? –

+0

今、コメントのコードを見ると、私は2つの問題を見ることができます。決してマネージコードから 'GetLastError'を呼び出すことはありません。 ['Marshal.GetLastWin32Error'](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getlastwin32error.aspx)を参照してください。これはなぜ重要なのかを説明するドキュメントです。次に、重複したI/Oを求めてください。あなたはそれを望まないし、P/invoke byte []バッファでは動かない。第3に、 'ReadFile'はハンドルを返さず、' bool'を返します。私はすでに私の答えでこれすべてをあなたに示しました。 –

関連する問題