DeviceIoControl
과 FSCTL_SET_ZERO_DATA
제어 코드를 C#으로 사용하려고합니다.FSCTL_SET_ZERO_DATA가있는 DeviceIoControl이 ERROR_INVALID_PARAMETER를 반환합니다.
파일 C:\tmp\test.txt
을 생성했으며 그 안에 텍스트 "aaaa"를 넣었습니다.
코드를 실행했는데 오류 번호가 표시되었습니다. 87
MSDN에 따르면 : "매개 변수가 잘못되었습니다."
DeviceIoControl
의 파라미터 번호 3) 입력 버퍼를 송신하고 있기 때문에 문제가 있음을 가정.
DeviceIoControl
은 false
을 반환합니다.
유효한 매개 변수를 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);
}
}
}
}
'nInBufferSize'는'FILE_ZERO_DATA_INFORMATION'의 크기이므로'16','nOutBufferSize'는 0이어야합니다. 문서를보십시오. – Aybe
감사합니다. 이제 작동합니다. 답변을 제출하여 답변으로 표시합니다. 다음과 같이 호출을 변경했습니다.'uint pBufferSize = 16; bool succeed = DeviceIoControl (handle, (uint) EIOControlCode.FsctlSetZeroData, pBuffer, pBufferSize, IntPtr.Zero, 0, bytesReturned, IntPtr.Zero); ' – E235