2017-02-23 15 views
1

DeviceIoControlFSCTL_SET_ZERO_DATA 제어 코드를 C#으로 사용하려고합니다.FSCTL_SET_ZERO_DATA가있는 DeviceIoControl이 ERROR_INVALID_PARAMETER를 반환합니다.

파일 C:\tmp\test.txt을 생성했으며 그 안에 텍스트 "aaaa"를 넣었습니다.

코드를 실행했는데 오류 번호가 표시되었습니다. 87
MSDN에 따르면 : "매개 변수가 잘못되었습니다."

enter image description here

가 난 데이터없이 ( DeviceIoControl의 파라미터 번호 3) 입력 버퍼를 송신하고 있기 때문에 문제가 있음을 가정.

DeviceIoControlfalse을 반환합니다.
유효한 매개 변수를 DeviceIoControl에 넣고 FSCTL_SET_ZERO_DATA으로 입력하면 true을 반환 할 수 있습니까?

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program2 
    { 
     [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] 
     static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, 
IntPtr lpInBuffer, uint nInBufferSize, 
IntPtr lpOutBuffer, uint nOutBufferSize, 
out uint lpBytesReturned, IntPtr lpOverlapped); 

     [Flags] 
     public enum EMethod : uint 
     { 
      Buffered = 0, 
      InDirect = 1, 
      OutDirect = 2, 
      Neither = 3 
     } 

     [Flags] 
     public enum EFileDevice : uint 
     { 
      FileSystem = 0x00000009 
     } 

     [Flags] 
     public enum EIOControlCode : uint 
     { 
      FsctlSetZeroData = (EFileDevice.FileSystem << 16) | (50 << 2) | EMethod.Buffered | (FileAccess.Write << 14), 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     struct FILE_ZERO_DATA_INFORMATION 
     { 
      public FILE_ZERO_DATA_INFORMATION(long offset, long count) 
      { 
       FileOffset = offset; 
       BeyondFinalZero = offset + count; 
      } 

      public long FileOffset; 
      public long BeyondFinalZero; 
     } 

     [DllImport("kernel32.dll")] 
     public static extern uint GetLastError(); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern IntPtr CreateFile(
     [MarshalAs(UnmanagedType.LPTStr)] string filename, 
     [MarshalAs(UnmanagedType.U4)] FileAccess access, 
     [MarshalAs(UnmanagedType.U4)] FileShare share, 
     IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero 
     [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, 
     uint flagsAndAttributes, 
     IntPtr templateFile); 

     static void Main(string[] args) 
     { 
      IntPtr handle = CreateFile(@"C:\tmp\test.txt", FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, (int)FileAttributes.Normal, IntPtr.Zero); 

      long length = 2; 
      FILE_ZERO_DATA_INFORMATION data = new FILE_ZERO_DATA_INFORMATION(0, length); 
      uint structSize = (uint)Marshal.SizeOf(data); 
      IntPtr pBuffer = Marshal.AllocHGlobal((int)structSize); 


      uint bytesReturned = 0; 
      bool succeed = DeviceIoControl(handle, (uint)EIOControlCode.FsctlSetZeroData, pBuffer, 5, IntPtr.Zero, 5, out bytesReturned, IntPtr.Zero); 

      // bool succeed = DeviceIoControl(handle, (uint)EIOControlCode.FsctlSetZeroData, IntPtr.Zero, 0, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); 
      if (succeed) 
      { 
       Console.WriteLine("Works fine"); 
      } 
      else 
      { 
       uint err = GetLastError(); 
       Console.WriteLine("Error number: {0}", err); 
      } 
     } 

    } 
} 
+1

'nInBufferSize'는'FILE_ZERO_DATA_INFORMATION'의 크기이므로'16','nOutBufferSize'는 0이어야합니다. 문서를보십시오. – Aybe

+0

감사합니다. 이제 작동합니다. 답변을 제출하여 답변으로 표시합니다. 다음과 같이 호출을 변경했습니다.'uint pBufferSize = 16; bool succeed = DeviceIoControl (handle, (uint) EIOControlCode.FsctlSetZeroData, pBuffer, pBufferSize, IntPtr.Zero, 0, bytesReturned, IntPtr.Zero); ' – E235

답변

1

@Aybe.

수정은 다음과 같습니다 가끔 함수가 사실이고 언젠가 false를 반환합니다, 추가하지 않을 경우

uint pBufferSize = 16; 
Marshal.StructureToPtr(data, pBuffer, false); 
bool succeed = DeviceIoControl(handle, (uint)EIOControlCode.FsctlSetZeroData, pBuffer, pBufferSize, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); 
  • 매우 중요한

    Marshal.StructureToPtr(data, pBuffer, false);

을 추가 할 수 있습니다.

Here은 C#에서 FSCTL을 사용하는 코드에 대한 참조입니다.

+0

여기에 몇 가지 추가 담당자가 있습니다. 당신을위한 포인트 :) – Aybe